zloirock/core-js · error · SyntaxError
Malformed padding: only one =
Error message
Malformed padding: only one =
What it means
In a 4-character chunk encoding 2 bytes, the base64 spec requires the second padding '=' to follow the first. If the chunk has exactly 2 characters of data and the remaining input ends (or does not contain a second '=') without providing the second '=', fromBase64 throws this SyntaxError because a 2-byte chunk must be terminated by '=='.
Source
Thrown at packages/core-js/internals/uint8-from-base64.js:124
throw new SyntaxError('Missing padding');
}
}
read = stringLength;
break;
}
var chr = at(string, index);
++index;
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) {View on GitHub (pinned to 84e45fba09)
Solutions
- Ensure every 2-byte final chunk ends with '==' — append the missing '=' (e.g. 'AB=' → 'AB==').
- Verify the string wasn't truncated by a length limit; compare with the expected encoded length ((n+2)/3*4 rounded up).
- Pass lastChunkHandling: 'loose' if you intentionally accept non-standard single-padded input only where supported.
- Use lastChunkHandling: 'stop-before-partial' if you want to stop at an incomplete final chunk instead of throwing.
Example fix
// before
Uint8Array.fromBase64('QUJD QQ=', { lastChunkHandling: 'strict' }); // Malformed padding: only one =
// after
const fixed = raw.endsWith('=') && !raw.endsWith('==') ? raw + '=' : raw;
Uint8Array.fromBase64(fixed, { lastChunkHandling: 'strict' }); Defensive patterns
Strategy: validation
Validate before calling
function hasCompletePadding(s) {
const compact = s.replace(/[\t\n\f\r ]/g, '');
const rem = compact.length % 4;
if (rem === 0) return true;
if (rem === 2) return compact.endsWith('==');
if (rem === 3) return compact.endsWith('=');
return false; // rem === 1 is always invalid
} Type guard
function isPaddedBase64(s) {
if (typeof s !== 'string') return false;
const c = s.replace(/[\t\n\f\r ]/g, '');
return c.length % 4 !== 1;
} Try / catch
try {
const bytes = Uint8Array.fromBase64(input);
} catch (e) {
if (e instanceof SyntaxError && e.message.includes('Malformed padding')) {
throw new TypeError('Base64 requires "==" for 2-byte final chunks');
}
throw e;
} Prevention
- Check that remainder-2 strings end with '==' before decoding.
- Watch for fixed-length truncation in transport/storage that drops trailing '='.
- Use lastChunkHandling: 'stop-before-partial' when partial final chunks are expected.
- Test round-trips: encode(decode(s)) === normalized(s).
When it happens
Trigger: Uint8Array.fromBase64('AB=') or fromBase64('AB= ') (trailing whitespace is skipped, then the string ends) — a chunk with chunk.length === 2 followed by '=' only once, when lastChunkHandling is not 'stop-before-partial'.
Common situations: Base64 strings truncated in transit (e.g. by fixed-width buffers or DB column limits), copy/paste dropping the final character, or strings produced by encoders emitting only one '=' for 2-byte final chunks.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Padding is too early
- Unexpected character after padding
- 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/992152b0a3149096.
Report an issue: GitHub.