Developer tools · Base64 encoder & decoder
Base64 padding explained: what the = signs mean and when they are required
· How it works
base64 encoding developer-workflow
The = at the end of a Base64 string is not decoration: it records how many bytes the last group was short. This post explains the arithmetic, why some strings have none, and why decoders disagree about missing padding.
The 'incorrect padding' exception from a token that looked fine — a failing decode and the one or two missing characters behind it
When a Base64 decoder reports incorrect padding, the string looks complete but carries a structural error. The equals signs are not cosmetic: each encodes how many bytes the final group was short, allowing the decoder to know exactly when real data ended. Understanding those = signs—and why strict decoders reject strings without them—transforms a mysterious error into predictable arithmetic. A JWT segment might have one =, none, or two. An API response might end cleanly without padding.
These represent intentional choices, not implementation variants. The decoding process does not require padding mechanically. Padding exists to make output unambiguous: given only a Base64 string with no metadata about length, the decoder reads padding and knows exactly where data ended. Base64 encodes groups of three bytes into four characters. Three bytes are 24 bits, regrouping perfectly into four 6-bit indices; each picks one of 64 Base64 symbols. When input is not a multiple of three, the encoder faces leftovers: one or two bytes cannot divide evenly by three.
Groups of three bytes, blocks of four characters — why input length modulo 3 decides whether zero, one or two = signs appear
The encoder pads those groups by shifting bits into first indices, leaving finals zero. To mark this intentional, it appends = signs: zero for complete groups, one for two-byte finals, two for one-byte finals. The arithmetic is deterministic: knowing input length in bytes lets you compute padding immediately. One byte produces two Base64 characters plus two =. Two bytes produce three characters plus one =. Three bytes produce four with no padding.
Any input not a multiple of three bytes will have padding; any that is a multiple will not. This is not choice—it is arithmetic. A string with no padding must represent three bytes. A string with one equals must represent two. Padding encodes input length modulo three. Examine transformation of three inputs: single a, pair ab, triple abc. ASCII a is byte 0x61; Base64 encodes it as 0x61 00 00, regrouping into six-bit groups.
What the padding bits contain and why a strict decoder checks them — the bits that must be zero and what canonical encoding means
The indices 24, 4, 0, 0 map to Y, E, A, A. Because two groups were padding, the encoder appends two = signs, producing YQ==. For ab, bytes 0x61 0x62 become 0x61 0x62 00. Bits regroup to indices 24, 22, 8, 0, output YWI=. For abc, bytes regroup to indices 24, 22, 9, 35, output YWJj with no padding. Padding is not arbitrary: it falls out of bit layout. When you decode a Base64 string, the decoder reads each character, looks up its six-bit index, packs bits into bytes.
For YQ==, characters Y, E, A, A unpack to bits. Regrouping into eight-bit bytes gives one byte, 0x61. The decoder discards padding bits (trailing zeros) and reports one byte. A strict decoder checks that padding bits are actually zero; if not, the input was not canonical, meaning someone encoded using different bit layout and decode is ambiguous. Systems omitting padding entirely make deliberate trade-offs. JWT segments use Base64url without padding, relying on consumers knowing expected output length or inferring it.
Worked example: encoding 'a', 'ab' and 'abc' by hand — three inputs, three padding outcomes, shown bit by bit
RFC 4648 allows padding absent but instructs decoders to accept it if present. Code libraries differ: some will restore missing padding and proceed; others will fail. When you encounter tokens that fail decoding, appending the right number of = signs often fixes it. Required = signs are always zero, one or two, depending on string length modulo four. If a Base64 string length is not a multiple of four, padding is definitely missing or corrupt.
A length of 5 cannot be valid Base64: each complete character encodes six bits, so four characters encode 24 bits (three bytes), and five encode 30 bits, which is not a multiple of eight and cannot become bytes. The decoder must either reject this or add padding. If length is 2 modulo 4, add two =. If 3 modulo 4, add one =. If 0 modulo 4, add none. A string of length 3 lacks its = it needs; add one and it becomes valid before decoding.
Why some systems drop padding entirely — JWT segments and URL-safe tokens that omit = and how to restore it from the length
Concatenating two padded Base64 strings broken if padding left in place. Two separate encodes joined directly produce stray padding characters that break the decoding alphabet. This is why some systems strip padding before concatenating: a token composed of three Base64url segments joined by dots has no padding within segments, making concatenation straightforward. If building a Base64 value from parts, verify whether each part is padded and strip or add padding consistently before any operations.
The Base64 encoder & decoder applies RFC 4648, which requires padding by default. When you enter text and request base64 output, the tool produces a padded result: the canonical form. If you see Base64 without padding and want to decode it, check whether your decoder accepts missing padding. The tool accepts both padded and unpadded input and correctly recovers original bytes. For debugging, counting length modulo four tells you whether padding was stripped, and the formula tells what padding should be present.
Common mistakes: trimming = as if it were whitespace, or concatenating two padded strings — how each corrupts the decode
Base32 and Base16 (hexadecimal) have different padding rules defined in RFC 4648 sections 6 and 7. Base32 uses = but final group can be 2, 4, 5, 7, or 8 characters depending on input length modulo five. Hexadecimal requires no padding; it always maps one byte to two characters with no remainder. MIME Base64 wrapping touches padding: a 76-column wrapped string still has padding at the very end, just several lines later.
Understanding padding for Base64 is about understanding bit layout and input length modulo three; once you see arithmetic, padding becomes a direct consequence, not a rule to memorize. Padding is derivable, not magical.
What this does not cover — base32 and base16 padding rules, and MIME line-length conventions
Given a Base64 string of any length, you can restore the canonical padded form by dividing character count by four, taking remainder, and appending the corresponding number of = signs. This is why missing = is fixable and why strict decoders can be forgiving: padding carries information (which branch of three cases your input fell into), but that information can be computed from length alone.
The Base64 encoder & decoder shows padded output immediately so you can compare decoded bytes to original text and verify round trip worked. Base64 and related encodings extend the principle of regrouping bits into different character widths. RFC 4648 specifies all three, and understanding one makes others conceptually simple. The key insight is that encoding is pure bit manipulation: pick your alphabet size, group your bits accordingly, look up each group in a table.
Takeaway: padding is derivable, so a missing = is fixable — how the Base64 encoder & decoder shows you the padded canonical form of any text you encode
Decoding reverses: look up each character, extract bits, regroup them, write bytes. This deterministic two-way mapping is why Base64 works reliably across all platforms and languages. Errors in encoding and decoding often trace to misunderstanding padding or alphabet differences. If decode fails with padding errors, check whether decoder expects canonical Base64 (strictly padded) or accepts variants. If it fails with character errors, check whether input is base64url and decoder expects standard Base64.
The Base64 encoder & decoder accepts both alphabets and validates padding consistently, so any hand-computed example can be verified instantly. Testing encoding by decoding it back is surest way to catch mistakes before they cause production problems.