Base64 Image Not Showing? 10 Common Causes and How to Fix Them
Published April 28, 2026 · 8 min read
You've encoded an image to Base64, pasted the data URI into your HTML, and… nothing. A broken image icon stares back at you. Or worse — it works in Chrome but breaks in Safari, works locally but fails in production.
Base64 image failures are frustrating because the string looks correct at a glance. The real cause is usually hiding in a subtle detail: a missing character in the prefix, invisible whitespace injected during copy-paste, or a backend that silently double-encoded your data. This guide covers all 10 common causes with exact code examples and fixes.
Quick Reference: Symptom → Cause → Fix
Start here. Find your symptom, check the likely cause, and jump to the detailed fix below.
| # | Symptom | Likely Cause | Quick Fix |
|---|---|---|---|
| 1 | 404 / broken icon | Missing data: prefix | Add data:image/...;base64, |
| 2 | Blank / no render | ; → , typo | Fix semicolon in prefix |
| 3 | Blank / no render | Missing comma after base64 | Add comma: base64, |
| 4 | Partial / corrupted image | String truncation | Use TEXT column type |
| 5 | InvalidCharacterError | Spaces / illegal chars | str.replace(/\s/g, '') |
| 6 | Works in code, breaks in HTML | Newline \n pollution | Strip \r\n |
| 7 | Inconsistent across browsers | Padding = stripped | URL-encode or re-pad |
| 8 | Usually works fine | MIME mismatch | Fix for correctness |
| 9 | Broken icon, string ~33% too long | Double encoding | Remove extra encode step |
| 10 | Broken icon, \/ in string | JSON / URL escape pollution | Use JSON.parse() |
Prefix Errors: The data: URI Is Malformed
The data URI scheme has a strict syntax. One wrong character and the browser treats your Base64 string as a broken URL instead of image data.
Cause 1: Missing the entire data URI prefix
If you set src directly to the raw Base64 string without the data:image/...;base64, prefix, the browser interprets it as a relative URL path — resulting in a 404.
❌ <img src="iVBORw0KGgo..." />
✅ <img src="data:image/png;base64,iVBORw0KGgo..." /> Cause 2: Semicolon written as comma
Writing data:image/png,base64,... instead of data:image/png;base64,... makes the browser treat base64,... as plain text content rather than a Base64 encoding indicator.
❌ data:image/png,base64,iVBORw0KGgo...
✅ data:image/png;base64,iVBORw0KGgo... Cause 3: Missing comma after "base64"
The comma between base64 and the actual data is required. Without it — data:image/png;base64iVBOR... — the browser reads base64iVBOR... as a charset name, not encoded data.
❌ data:image/png;base64iVBORw0KGgo...
✅ data:image/png;base64,iVBORw0KGgo... Encoding Corruption: The Base64 String Itself Is Broken
Even with a correct prefix, the encoded payload can be silently corrupted during storage, transmission, or copy-paste.
Cause 4: String truncation
Database columns with character limits (e.g., VARCHAR(65535)) silently cut off Base64 strings. A 100KB PNG produces ~136,000 Base64 characters. If the column truncates at 65,535, you get a half-decoded, corrupted image. Fix: Use TEXT or LONGTEXT column types for Base64 storage.
Cause 5: Illegal characters (spaces, special chars)
Valid Base64 uses only A-Z, a-z, 0-9, +, /, and =. Spaces introduced during copy-paste will cause atob() to throw InvalidCharacterError. Fix: Strip all whitespace before use: str.replace(/\s/g, '').
Cause 6: Newline pollution
Tools like openssl base64 insert a \n every 76 characters by default (per RFC 2045). These literal newlines break data URIs in HTML. Fix: Use openssl base64 -A (single-line output) or strip newlines: str.replace(/[\r\n]/g, '').
Cause 7: Padding stripped by URL parsing
Base64 padding characters (=) are often stripped when the string passes through URL query parameters, since = is a reserved character in URLs. Some browsers tolerate missing padding, others don't — causing inconsistent behavior across environments. Fix: URL-encode the Base64 string before putting it in a query parameter, or re-pad it on the receiving end.
MIME Mismatch: Does It Actually Break?
This one surprises most developers: declaring the wrong MIME type usually doesn't break the image.
Cause 8: Declared MIME doesn't match actual file type
If you write data:image/png;base64,/9j/4AAQ... (JPEG data with a PNG MIME type), most modern browsers will still render it correctly thanks to content sniffing. However, it can fail in two scenarios: (1) strict Content Security Policy (CSP) with MIME enforcement, and (2) server-side processing that trusts the declared MIME for format conversion. Verdict: Fix it for correctness, but it's rarely the actual cause of display failure.
Pipeline Errors: Corrupted Before It Reaches the Browser
These are the hardest to diagnose because the Base64 string looks correct in your code — the corruption happens during serialization or transmission.
Cause 9: Double Base64 encoding
A backend that encodes already-encoded data produces a Base64 string of a Base64 string. The result is ~33% longer than expected and decodes to text, not binary image data. How to detect: Decode once — if the result looks like another Base64 string (starts with letters and ends with =), you've been double-encoded. Fix: Remove the redundant encoding step in your backend pipeline.
Cause 10: JSON escape or URL-encoding pollution
Base64 strings contain / characters. Some JSON serializers escape these as \/. If the frontend reads the raw JSON string without proper parsing (JSON.parse), the extra backslashes corrupt the data. Similarly, passing Base64 through URL parameters without encoding turns + into spaces and strips = padding. Fix: Always use JSON.parse() for JSON data. For URL transport, use encodeURIComponent().
Systematic Debugging Template
When you're stuck, follow this step-by-step process to isolate the issue:
- Test the data URI in the browser address bar — Paste the complete
data:image/...;base64,...string directly into your browser's address bar. If it renders, the problem is in how your application injects the string. - Check the browser console — Press F12 and look for errors like
net::ERR_INVALID_URLor CSP violations in the Console tab. - Verify string length — Compare the length of the Base64 string at the source (backend) vs. what arrives at the frontend. A mismatch means truncation or corruption in transit.
- Decode and inspect — Use
atob()in the console to decode the first few characters. If it throwsInvalidCharacterError, the string contains illegal characters. - Check for double encoding — Decode once. If the result is another Base64-looking string, decode again. If the second decode produces binary data, your pipeline has a redundant encoding step.
Validate Base64 Instantly with ViewJSON
Instead of manually inspecting Base64 strings, paste your JSON into ViewJSON. It automatically detects Base64-encoded media using magic number detection and renders inline previews — if the preview appears, your Base64 is valid. If it doesn't, you know exactly which field is corrupted.
Related Article
How to Debug Base64 Images in JSON API Responses →Try It Now
Paste your Base64 string and see if it renders — instantly, in the browser, with no upload.
Open ViewJSON →