zloirock/core-js · error · SyntaxError
Unexpected character after padding
Error message
Unexpected character after padding
What it means
After a complete padded chunk, the base64 spec allows no further data: once padding '=' has been consumed and remaining ASCII whitespace skipped, any non-whitespace character remaining in the string means there is data after the final padding, which is invalid. fromBase64 throws this SyntaxError rather than silently ignoring the trailing content.
Source
Thrown at packages/core-js/internals/uint8-from-base64.js:132
if (chr === '=') {
if (chunk.length < 2) {
throw new SyntaxError('Padding is too early');
}
index = skipAsciiWhitespace(string, index);
if (chunk.length === 2) {
if (index === stringLength) {
if (lastChunkHandling === 'stop-before-partial') {
break;
}
throw new SyntaxError('Malformed padding: only one =');
}
if (at(string, index) === '=') {
++index;
index = skipAsciiWhitespace(string, index);
}
}
if (index < stringLength) {
throw new SyntaxError('Unexpected character after padding');
}
written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, lastChunkHandling === 'strict'), written);
read = stringLength;
break;
}
if (!hasOwn(alphabet, chr)) {
throw new SyntaxError('Unexpected character');
}
var remainingBytes = maxLength - written;
if (remainingBytes === 1 && chunk.length === 2 || remainingBytes === 2 && chunk.length === 3) {
// special case: we can fit exactly the number of bytes currently represented by chunk, so we were just checking for `=`
break;
}
chunk += chr;
if (chunk.length === 4) {
written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written);
chunk = '';View on GitHub (pinned to 84e45fba09)
Solutions
- Remove all characters after the final '=' in the string before decoding.
- If multiple values are being concatenated, decode each separately instead of joining the base64 strings.
- Trim the string and confirm it ends with padding only when it is genuinely the final chunk.
- Catch SyntaxError and reject the input at your API boundary with a clear message.
Example fix
// before
Uint8Array.fromBase64('QUJDRA==extra'); // Unexpected character after padding
// after
const idx = raw.indexOf('==');
const clean = idx !== -1 ? raw.slice(0, idx + 2) : raw;
Uint8Array.fromBase64(clean); Defensive patterns
Strategy: validation
Validate before calling
function hasNoTrailingData(s) {
const idx = s.indexOf('=');
if (idx === -1) return true;
return /^[\t\n\f\r ]*$/.test(s.slice(idx + 1)); // only whitespace may follow first '='
} Type guard
function isBareBase64(s) {
return typeof s === 'string' && /^[A-Za-z0-9+/=_\-\s]*$/.test(s);
} Try / catch
try {
const bytes = Uint8Array.fromBase64(input);
} catch (e) {
if (e instanceof SyntaxError && e.message.includes('after padding')) {
throw new TypeError('Base64 input has data after final padding — decode values separately');
}
throw e;
} Prevention
- Strip any data-URI prefix and trailing metadata before decoding.
- Never concatenate base64 strings; decode each part individually.
- Trim and validate the string ends exactly at padding.
- Enforce a strict regex (^[A-Za-z0-9+/]*={0,2}$) at the input boundary.
When it happens
Trigger: Uint8Array.fromBase64('AB==C') or any string where a '==' (or 'X=' two-byte chunk) terminated chunk is followed by more non-whitespace characters, with lastChunkHandling 'strict' or 'loose'.
Common situations: Concatenating two base64 strings where the first already ended with padding, embedding base64 inside a larger payload without delimiters, or appending suffixes (e.g. newlines mixed with stray characters, checksums) to encoded values.
Related errors
- Padding is too early
- Malformed padding: only one =
- Malformed padding: exactly one additional character
- Missing padding
- Unexpected character
AI-assisted analysis of zloirock/core-js@84e45fba09 (2026-08-30).
Data as JSON: /api/errors/478f7e0d6a1f10b2.
Report an issue: GitHub.