Mensagens de erro num relance
| Mensagem | Onde aparece | Causa mais provável |
|---|---|---|
binascii.Error: Incorrect padding | base64.b64decode do Python | Faltam = 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 4 | Python | Entrada truncada, ou -/_ descartados em silêncio |
binascii.Error: Only base64 data is allowed | Python com validate=True | Quebra de linha, espaço, - ou _ na entrada |
InvalidCharacterError: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded. | Chrome, Edge | Caracteres Base64URL, caracteres de lixo, comprimento inválido |
InvalidCharacterError: String contains an invalid character | Firefox | Igual ao anterior |
InvalidCharacterError: Invalid character | atob do Node.js | Igual ao anterior |
IllegalArgumentException (“Illegal base64 character …”) | java.util.Base64 do Java | Decodificador errado para o alfabeto, ou quebras de linha |
FormatException | Convert.FromBase64String do .NET | Caracteres Base64URL ou falta de preenchimento |
base64: invalid input | base64 -d do GNU coreutils | Caracteres 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%2Fvindo 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ém | Use |
|---|---|
+ 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ê | Original | O 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\0 | Hello | Bytes 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" | base64dáaGVsbG8K(com\n), enquantoecho -n "hello" | base64dáaGVsbG8=. Useprintf '%s'ouecho -n. +virou espaço. Em query strings de URL e corpos de formulário,+significa espaço.URLSearchParams("t=PGI+Ym9sZDwvYj4=").get("t")retornaPGI Ym9sZDwvYj4=. Alguns decodificadores então lançam erro, outros descartam o espaço e geram lixo. Aplique percent-encoding ao Base64 comencodeURIComponentantes de colocá-lo numa URL, ou use Base64URL.- Percent-encoding esquecido.
SGk%2FPg%3D%3Dprecisa ser decodificado como URL paraSGk/Pg==antes da decodificação Base64. - Escapes copiados de um JSON. Copiar uma string direto do JSON bruto pode trazer um
\nliteral (dois caracteres). O decodificador tolerante do Python descarta a barra invertida, mantém one 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 comvalidate=Truee 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.