How to validate a Base64 string
- Paste the string into Base64 to check. Line breaks, PEM armor and
data:prefixes can stay in; they are reported as findings and the rest is still analyzed. - Read the verdict at the top. Each problem is listed with its position, for example “at line 3, column 17 (char 169)”.
- Look at Your input, problems highlighted to see the offending characters marked in place.
- Check Which Base64 variants does it satisfy? to learn whether it is valid as standard, unpadded, URL-safe, MIME or PEM Base64, and why not where it fails.
- Press Fix it to switch to repair mode, which cleans the string up.
What the validator checks
- Characters outside the alphabet, shown with their Unicode code point so invisible ones such as a non-breaking space (U+00A0) or a zero-width space (U+200B) become visible.
- Mixed alphabets:
+and/from standard Base64 together with-and_from Base64URL in one string. =in the middle, which almost always means two encoded values were glued together.- Impossible length: after removing padding, a length with remainder 1 when divided by 4 cannot come out of any encoder. A character is missing or extra.
- Padding: missing, too many, or not matching the data length.
- Non-canonical trailing bits in the last character (RFC 4648 §3.5).
- Whitespace and line wrapping: spaces and tabs, the line width, and whether lines end in CRLF, LF or a mix.
Details adds the length, length mod 4, padding state, alphabet, decoded size and the detected content type. The highlighted copy of the input is limited to the first 20,000 characters, but the analysis always covers the whole string.
Same string, different decoders
“Valid” depends on who is asking. These five strings were run through four common decoders (Python 3.13, Node.js 24, the WHATWG atob and GNU coreutils 9.7):
| Input | Problem | Python b64decode(s, validate=True) | Node Buffer.from(s, "base64") | atob(s) | base64 -d |
|---|---|---|---|---|---|
SGVsbG8gd29ybGQ | missing = | error | Hello world | Hello world | Hello world |
SGVsbG9= | non-canonical last char | Hello | Hello | Hello | error |
SGVsbG8=V29ybGQ= | two values glued | error | Hello (the rest is dropped) | error | HelloWorld |
SGVsbG8gd | remainder 1 | error | Hello | error | error |
SGVs bG8= | a space | error | Hello | Hello | error |
The dangerous cell is Node quietly returning Hello for the glued input and losing half the data with no error. This tool therefore reports every deviation, including ones your own decoder tolerates. The variant table then tells you which strict format the string satisfies.
Is a valid string really Base64?
abcd, test and 1234 are all valid Base64. Each decodes to three random-looking bytes. So the tool also answers Is this really Base64? with a score from 0 to 100 and the reasons behind it, each marked as pointing towards or away from Base64:
- for: correct padding, mixed upper and lower case with digits, high character variety, an
eyJstart (Base64 for{", typical of JSON and JWTs), or bytes that decode to a known file type or readable text; - against: only letters (could be a word), only hex digits (could be a hex string), only digits (probably a number), a single letter case, or a very short string.
Treat the score as a hint: it is a heuristic, and a short string can fool it either way.
Checking Base64 in code
The strictest practical test is a round trip: decode, re-encode and compare. It rejects whitespace, missing padding and non-canonical endings in one go.
import base64
def is_canonical_base64(s):
try:
return base64.b64encode(base64.b64decode(s, validate=True)).decode() == s
except ValueError:
return False
In Node.js the same idea is Buffer.from(s, "base64").toString("base64") === s. A regular expression such as ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$ checks the alphabet and length, but it accepts SGVsbG9= and the empty string. For URL-safe strings, convert them first or use the matching alphabet; see Base64 vs Base64URL. Error messages from specific languages are collected in Base64 errors.
FAQ
How can I tell if a string is Base64?
Strictly, a string is valid standard Base64 if it uses only A–Z, a–z, 0–9, + and /, its length is a multiple of 4, and at most two = sit at the end. Plenty of ordinary words pass that test, so the tool adds a 0–100 score based on what the string looks like and what it decodes to.
Why does my Base64 decode in one language but fail in another?
Decoders differ in how strict they are. Node’s Buffer.from accepts almost anything, Python’s b64decode(s, validate=True) rejects missing padding, and GNU base64 -d rejects non-canonical final characters. The table above shows the same five strings in four decoders.
What is non-canonical Base64?
The last character carries a few unused bits that should be zero. SGVsbG8= and SGVsbG9= both decode to Hello, but only the first is canonical. RFC 4648 lets decoders reject the second, and re-encoding never reproduces it.
Is a valid Base64 string safe to decode?
Validity says nothing about the content. The Details section shows the decoded size and the detected content type, with a link to the matching decoder, so you know whether it is text, an image or something else before you save it.