Enviar um arquivo
  1. base64hub
  2. Aprenda Base64
  3. Erros de Base64
Solução de problemas

Erros ao decodificar Base64 e como resolvê-los

A maioria das falhas de Base64 vem de cinco causas: alfabeto errado, falta de preenchimento, caracteres perdidos, charset errado ou dados codificados duas vezes. Encontre a sua mensagem de erro abaixo e vá direto à solução.

Mensagens de erro num relance

MensagemOnde apareceCausa mais provável
binascii.Error: Incorrect paddingbase64.b64decode do PythonFaltam = no final, muitas vezes por ser Base64URL ou uma string cortada
binascii.Error: Invalid base64-encoded string: number of data characters (5) cannot be 1 more than a multiple of 4PythonEntrada truncada, ou -/_ descartados em silêncio
binascii.Error: Only base64 data is allowedPython com validate=TrueQuebra de linha, espaço, - ou _ na entrada
InvalidCharacterError: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.Chrome, EdgeCaracteres Base64URL, caracteres de lixo, comprimento inválido
InvalidCharacterError: String contains an invalid characterFirefoxIgual ao anterior
InvalidCharacterError: Invalid characteratob do Node.jsIgual ao anterior
IllegalArgumentException (“Illegal base64 character …”)java.util.Base64 do JavaDecodificador errado para o alfabeto, ou quebras de linha
FormatExceptionConvert.FromBase64String do .NETCaracteres Base64URL ou falta de preenchimento
base64: invalid inputbase64 -d do GNU coreutilsCaracteres fora do alfabeto

Como resolver erros do decodificador

“Incorrect padding” no Python

A saída Base64 sempre tem comprimento múltiplo de 4, completado com = no final. O decodificador do Python exige o preenchimento:

>>> import base64
>>> base64.b64decode("SGVsbG8")
Traceback (most recent call last):
  ...
binascii.Error: Incorrect padding
>>> base64.b64decode("SGVsbG8=")
b'Hello'

Falta de preenchimento geralmente significa que a string é Base64URL (JWTs, tokens em URLs e muitas APIs descartam o =) ou que algo a cortou. Recoloque o preenchimento:

s = "SGVsbG8"
s += "=" * (-len(s) % 4)

Quando o comprimento é um a mais que um múltiplo de 4, o preenchimento não resolve. Aí o Python informa number of data characters (5) cannot be 1 more than a multiple of 4. Um único caractere que sobra guarda só 6 bits, então parte dos dados está faltando. Também dá para cair nessa mensagem sem uma string cortada: sem validate=True, o Python descarta os caracteres fora do alfabeto, inclusive - e _. base64.b64decode("SGk_Pg==") descarta o _ e fica com 5 caracteres de dados. Use base64.urlsafe_b64decode para entrada Base64URL.

“Invalid character” e falhas do atob

Os navegadores implementam o atob com o mesmo algoritmo, mas escrevem o erro de formas diferentes. O Chrome diz “The string to be decoded is not correctly encoded”, o Firefox diz “String contains an invalid character”, o Node.js diz “Invalid character”. Os três lançam um InvalidCharacterError para estas entradas:

  • Caracteres Base64URL. atob("SGk_Pg") falha por causa do _. Troque antes - por + e _ por /.
  • Comprimento 4n+1 depois de remover os espaços em branco, como em atob("A").
  • Caracteres que não deveriam estar ali: aspas copiadas de um JSON, um prefixo data:, um %2F vindo da codificação de URL.

O atob perdoa algumas coisas. Ele pula espaços e quebras de linha e aceita a falta de preenchimento quando o comprimento fecha, então atob("SGVsbG8") retorna "Hello". O erro espelhado, o btoa falhando com “characters outside of the Latin1 range”, tem a ver com texto Unicode e é explicado em Uint8Array.toBase64.

Um decodificador tolerante que lida com os dois alfabetos, espaços em branco e falta de preenchimento:

function decodeLoose(s) {
  s = s.replace(/\s+/g, "").replace(/-/g, "+").replace(/_/g, "/");
  s += "=".repeat((4 - (s.length % 4)) % 4);
  return Uint8Array.from(atob(s), (c) => c.charCodeAt(0));
}

new TextDecoder().decode(decodeLoose("SGk_Pg")); // "Hi?>"

O equivalente em Python:

import base64

def b64decode_any(s: str) -> bytes:
    s = "".join(s.split())
    s = s.replace("-", "+").replace("_", "/")
    s += "=" * (-len(s) % 4)
    return base64.b64decode(s, validate=True)

A ferramenta Reparar Base64 aplica a mesma limpeza e diz o que mudou.

“Illegal base64 character” no Java e FormatException no .NET

O java.util.Base64 do Java traz três decodificadores, e cada um é rígido com o próprio alfabeto. A mensagem indica o caractere problemático em hex: 5f é _, 2d é -, 2f é /, 20 é um espaço, a é uma quebra de linha.

A entrada contémUse
+ e /Base64.getDecoder()
- e _Base64.getUrlDecoder()
Quebras de linha (MIME, corpos PEM)Base64.getMimeDecoder()

O decodificador básico rejeita quebras de linha e espaços. Ele aceita a falta de preenchimento, então SGVsbG8 decodifica sem reclamação.

O Convert.FromBase64String do .NET lança FormatException para caracteres Base64URL e para falta de preenchimento. Ele pula espaços e quebras de linha. Corrija o alfabeto e o preenchimento como mostrado acima antes de chamá-lo. Veja Base64 em Java e Base64 em C# para exemplos completos.

O texto sai embaralhado

A decodificação deu certo, mas o texto parece errado. O Base64 guarda bytes, e esses bytes foram gerados a partir de um texto com alguma codificação de caracteres. Leia-os de volta com outra e você obtém mojibake.

Você vêOriginalO que aconteceu
CaféCaféBytes UTF-8 lidos como Latin-1 ou Windows-1252
Caf�CaféBytes Windows-1252 lidos como UTF-8
H e l l o ou H\0e\0l\0l\0o\0HelloBytes UTF-16LE lidos como UTF-8

A primeira linha é a armadilha clássica do atob. atob("Q2Fmw6k=") retorna "Café", porque o atob transforma cada byte num caractere. Decodifique os bytes como UTF-8:

const bytes = Uint8Array.from(atob("Q2Fmw6k="), (c) => c.charCodeAt(0));
new TextDecoder().decode(bytes); // "Café"

UTF-16LE é comum em ferramentas do Windows: o -EncodedCommand do PowerShell e muitas APIs do .NET o produzem. O Base64 para texto permite trocar o charset até a saída ficar legível, e o Base64 para UTF-16 cuida do caso de caracteres largos.

A saída parece binária

Se o resultado decodificado está cheio de �, caracteres de controle ou fragmentos como PNG, PK e %PDF, o payload é um arquivo. Olhe os primeiros caracteres do Base64: iVBORw0KGgo é um PNG, JVBERi0 um PDF, H4sI gzip. A lista completa está em prefixos Base64 comuns. Abra os dados com Base64 para arquivo, que detecta o formato e oferece o download. Para H4sI, use decodificar gzip em Base64.

A decodificação dá bytes diferentes do esperado

Nenhum erro, mas os bytes estão errados. Estes são os motivos habituais:

  • Uma quebra de linha no final na hora de codificar. echo "hello" | base64 dá aGVsbG8K (com \n), enquanto echo -n "hello" | base64 dá aGVsbG8=. Use printf '%s' ou echo -n.
  • + virou espaço. Em query strings de URL e corpos de formulário, + significa espaço. URLSearchParams("t=PGI+Ym9sZDwvYj4=").get("t") retorna PGI Ym9sZDwvYj4=. Alguns decodificadores então lançam erro, outros descartam o espaço e geram lixo. Aplique percent-encoding ao Base64 com encodeURIComponent antes de colocá-lo numa URL, ou use Base64URL.
  • Percent-encoding esquecido. SGk%2FPg%3D%3D precisa ser decodificado como URL para SGk/Pg== antes da decodificação Base64.
  • Escapes copiados de um JSON. Copiar uma string direto do JSON bruto pode trazer um \n literal (dois caracteres). O decodificador tolerante do Python descarta a barra invertida, mantém o n e retorna bytes errados sem erro: b64decode("SGVs\\nbG8=") dá b'Hel\x9d\xb1\xbc'. Faça o parsing do JSON em vez de copiar dele. O decodificador Base64 de JSON faz isso para cada campo.
  • Espaços em branco: rígido versus tolerante. Python sem validate=True, atob, .NET e o decodificador MIME do Java pulam quebras de linha. Python com validate=True e o decodificador básico do Java as rejeitam. Dados MIME e PEM vêm quebrados em 76 ou 64 caracteres, então escolha um decodificador que os aceite.

Dados codificados duas vezes

Decodificar U0dWc2JHOGdkMjl5YkdRaA== dá SGVsbG8gd29ybGQh, que de novo é Base64 válido e decodifica para Hello world!. Quando o resultado de uma decodificação tem só caracteres Base64 e comprimento múltiplo de 4, suspeite de dupla codificação.

Isso acontece muito com Secrets do Kubernetes. Os valores em data: são Base64, e o kubectl create secret --from-literal codifica por você. Se você codificar o valor antes por conta própria, o pod recebe texto Base64 em vez da senha. Use stringData: para valores em texto puro ou confira o que está armazenado com o decodificador de Secrets do Kubernetes. Na dúvida, o validador de Base64 mostra se uma string é válida e quantos bytes ela contém.

Perguntas frequentes

Como resolver o binascii.Error: Incorrect padding?

Acrescente = até o comprimento ser múltiplo de 4: s += "=" * (-len(s) % 4). Se a string for Base64URL, troque também - por + e _ por /, ou use base64.urlsafe_b64decode.

Por que o atob falha com um JWT?

JWTs usam Base64URL, que tem - e _. O atob só conhece + e /. Converta os caracteres antes ou cole o token no decodificador de JWT.

Por que o texto decodificado mostra é em vez de é?

Os bytes são UTF-8, mas foram lidos como Latin-1 ou Windows-1252. Decodifique os bytes como UTF-8, por exemplo com TextDecoder em JavaScript ou .decode("utf-8") em Python.

Dá para consertar uma string Base64 com comprimento 4n+1?

Não. Um caractere que sobra carrega só 6 bits, menos que um byte, então falta pelo menos um caractere. Procure a fonte original ou confira onde a string foi cortada.

Como saber se os dados foram codificados em Base64 duas vezes?

Decodifique uma vez. Se o resultado for de novo uma string só com A-Z a-z 0-9 + / = e comprimento múltiplo de 4, decodifique outra vez.

Continue lendo