Fix Invalid Base64 Image Data: 6 Common Causes and How to Fix Each One

Your base64 image string refuses to decode — you get a broken image, a console error like InvalidCharacterError, or an API returns invalid_base64. The string itself is almost always the problem, not your decoder. Here are the six causes we see most often, and a quick fix for each.

Before debugging anything, paste your string into our base64-to-image decoder. It tells you immediately whether the payload is decodable, so you know which side of the pipeline is broken.

1. Missing or malformed data URI prefix

A data URI must look exactly like this:

data:image/png;base64,iVBORw0KGgoAAAANS...

Common mistakes: missing the data: scheme, missing the ;base64, separator, or a wrong MIME type (e.g. image/jpg instead of image/jpeg). If you store only the raw payload, do not add a prefix when decoding raw bytes — the prefix and the raw string are two different formats.

Fix: if the consumer expects a data URI, prepend the correct prefix for the actual format: data:image/jpeg;base64, for JPEG, data:image/png;base64, for PNG. Match the prefix to the real bytes, not the original file extension.

2. Whitespace and line breaks inside the payload

Many encoders (and email clients, and code formatters) wrap base64 at 76 characters. Most browser decoders tolerate newlines; many JSON parsers and API validators do not.

Fix: strip all whitespace before sending or storing the string:

const clean = raw.replace(/\s+/g, "");

3. URL-safe base64 characters (- and _)

JWTs and some APIs use URL-safe base64, which replaces + with - and / with _. The standard atob() and most image decoders expect the standard alphabet, so these strings fail with an invalid-character error.

Fix: convert back before decoding:

const standard = urlSafe.replace(/-/g, "+").replace(/_/g, "/");
// pad to a multiple of 4 if needed:
const padded = standard + "=".repeat((4 - (standard.length % 4)) % 4);

4. Truncated string

Copying a 500 KB base64 string from a log viewer or JSON pretty-printer often silently truncates it. A truncated payload decodes to garbage bytes, so the image never renders even though "the base64 looks fine."

Fix: check that the string length is a multiple of 4 (after removing whitespace) and that it ends with = or == padding only when expected. For images, also verify the leading magic bytes: PNG payloads start with iVBOR, JPEG with /9j/. If your string starts differently than its declared MIME type, it's truncated or mislabeled.

5. Double encoding

If someone base64-encoded an already-encoded string, you'll decode once and get… base64 again. This is one of the most reported debugging headaches.

Fix: decode once and inspect the result. If it still looks like base64 (only A–Z, a–z, 0–9, +, /, =), decode again. Our base64-to-image tool shows the decoded result instantly, so double encoding is obvious in one paste.

6. Wrong MIME type in the prefix

A data:image/png;base64, prefix wrapping JPEG bytes fails in strict renderers even though the payload is valid. The prefix is a promise to the decoder.

Fix: check the first characters of the payload — /9j/ = JPEG, iVBOR = PNG, UklGR = WebP, PHN2Zy = SVG, R0lGOD = GIF — and align the prefix. If you're converting between formats first, make sure the conversion actually happened before encoding.

Quick checklist

  1. Does it start with data:image/<type>;base64, (if a data URI is expected)?
  2. Any whitespace or newlines left inside?
  3. Any - or _ characters (URL-safe alphabet)?
  4. Is the length a multiple of 4?
  5. Do the first payload characters match the declared MIME type?
  6. Decode once — is the result still base64? (double encoding)

Frequently asked questions

Why does my Base64 image fail to decode?

Almost always the string itself, not the decoder: missing prefix, whitespace inside, URL-safe characters, truncation, double encoding, or a mismatched MIME prefix. Work through the checklist above.

How do I know if a Base64 string is a JPEG or a PNG?

Look at the first payload characters: /9j/ = JPEG, iVBOR = PNG, UklGR = WebP, PHN2Zy = SVG, R0lGOD = GIF. Align the data URI prefix with the actual bytes.

What are URL-safe Base64 characters?

A variant alphabet used in JWTs and some APIs: - instead of +, _ instead of /. Convert back to the standard alphabet and pad to a multiple of 4 before decoding.

How do I check if a Base64 string is truncated?

Length (after whitespace removal) must be a multiple of 4, and the leading magic bytes must match the declared type. A string that starts differently than it claims is truncated or mislabeled.

Related tools: decode and preview a string with base64 to image · encode the right way with image to base64 · format-specific encoders: JPG to base64 and PNG to base64 · more answers in the FAQ.