zloirock/core-js · error · SyntaxError
Malformed padding: exactly one additional character
Error message
Malformed padding: exactly one additional character
What it means
When decoding reaches the end of the input with a leftover partial chunk, 'loose' lastChunkHandling accepts a 2- or 3-character final chunk (without padding) but rejects a single leftover character, because one base64 char carries only 6 bits — not enough to encode any byte. This SyntaxError reports that exact case.
Source
Thrown at packages/core-js/internals/uint8-from-base64.js:102
if (into) notDetached(into.buffer);
var stringLength = string.length;
var bytes = into || $Array(floor(stringLength * 3 / 4));
var written = 0;
var read = 0;
var chunk = '';
var index = 0;
if (maxLength) while (true) {
index = skipAsciiWhitespace(string, index);
if (index === stringLength) {
if (chunk.length > 0) {
if (lastChunkHandling === 'stop-before-partial') {
break;
}
if (lastChunkHandling === 'loose') {
if (chunk.length === 1) {
throw new SyntaxError('Malformed padding: exactly one additional character');
}
written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written);
} else {
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) {View on GitHub (pinned to 84e45fba09)
Solutions
- Fix the source data — a single trailing base64 char is never valid; the string is truncated or corrupt.
- Use lastChunkHandling: 'stop-before-partial' to decode only up to the last complete chunk.
- Add missing padding: a 1-char tail cannot be padded to validity, so repair/re-request the data.
- Validate `string.length % 4 !== 1` before decoding.
Example fix
// before
Uint8Array.fromBase64('QQBj'); // chunks 'QQBj' ok — but 'QQBjx' leaves chunk 'x' -> SyntaxError
// after
const s = b64.replace(/\s/g, '');
if (s.length % 4 === 1) throw new Error('truncated base64');
Uint8Array.fromBase64(s); Defensive patterns
Strategy: validation
Validate before calling
const s = b64.replace(/\s/g, '');
if (s.length % 4 === 1) {
throw new Error('base64 input truncated: single trailing character cannot encode any byte');
} Type guard
function isDecodableBase64Length(s) { return s.replace(/\s/g, '').length % 4 !== 1; } Try / catch
try {
bytes = Uint8Array.fromBase64(b64);
} catch (e) {
if (e instanceof SyntaxError && /Malformed padding/.test(e.message)) {
bytes = Uint8Array.fromBase64(b64, { lastChunkHandling: 'stop-before-partial' });
} else throw e;
} Prevention
- Check that stripped base64 length % 4 !== 1 before decoding.
- Investigate any 1-char tail as data corruption/truncation — don't try to 'fix' it silently.
- Use 'stop-before-partial' when consuming streaming chunks of unknown completeness.
When it happens
Trigger: `Uint8Array.fromBase64('QQ A'.replace(/\s/g,''))`-style input whose final group is exactly 1 character, e.g. 'QUIx' (4+... wait) — concretely a string like 'QQB'+'j' where the last chunk after splitting into 4s is 'j'. Also whitespace-split strings that lost characters.
Common situations: Base64 strings truncated by one character during copy/paste or storage trimming, custom encoders emitting a lone trailing char, or regex/split processing that dropped '=' padding leaving one char.
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
- Missing padding
- Extra bits
- Incorrect `lastChunkHandling` option
- Padding is too early
- Malformed padding: only one =
AI-assisted analysis of zloirock/core-js@84e45fba09 (2026-08-30).
Data as JSON: /api/errors/fe6150a33a56ff66.
Report an issue: GitHub.