Why PNG Images Aren’t Showing on Websites and How to Fix Them
Find the exact reason a PNG is broken, downloaded, or missing—and fix paths, MIME types, CSP, permissions, CDN, cache, and browser issues.
Start with the network request, not the broken-image icon. Open your browser’s developer tools, reload the page, and inspect the PNG request. The HTTP status, response headers, and Console message usually identify the cause immediately:
| What you see | Most likely cause | First fix |
|---|---|---|
| 404 Not Found | Wrong URL, missing deployment, or filename case mismatch | Open the exact URL and compare its path and capitalization with the deployed file |
| 403 Forbidden | Permissions, access policy, signed URL, or CDN-to-origin failure | Allow the browser or CDN to read the object |
| 200 but downloads or renders incorrectly | Wrong Content-Type, often missing image/png |
Set the response MIME type to image/png |
| Console says CSP blocked it | img-src or default-src excludes the image origin |
Add the image or CDN origin to your Content-Security-Policy |
| Mixed-content or CORS error | HTTPS page loading HTTP image, or a cross-origin policy problem | Use HTTPS and configure the delivery layer for the required origin |
| Only one browser or user fails | Cache, extension, privacy tool, or security software | Retest in a private window and another browser |
1. Inspect the failed PNG request
- Open DevTools (Network tab), enable “Disable cache” while DevTools is open, and reload.
- Filter by
Imgor search for the filename. - Record the request URL, status code, redirect chain, response headers, and Console errors.
- Right-click the request and open it in a new tab. If the direct URL fails, the HTML or CSS is not the primary problem.
- Repeat in another browser or a private window to separate server failures from local browser state.
The broken-image icon is only a symptom. A 404, 403, policy violation, or invalid response header leads to a different fix.
2. Fix the URL, path, and filename case
Relative URLs resolve from the document URL. If a page moved from / to /docs/, src="images/logo.png" now requests /docs/images/logo.png. Use an absolute site path when the asset is rooted at the domain:
<img src="/images/logo.png" alt="Company logo">
Check all of these details:
- The file is included in the production build and deployment artifact.
- The requested directory matches the deployed directory.
- Every character has the same capitalization. Linux hosts commonly treat
Logo.PNGandlogo.pngas different files. - The URL is correctly encoded if a filename contains spaces or non-ASCII characters.
- Rewrite rules are not sending the image request to an HTML fallback.
Use curl to verify the deployed path:
curl -I https://example.com/images/logo.png
curl -L -o /dev/null -w "%{http_code} %{content_type} %{url_effective}\n" https://example.com/images/logo.png
A 404 confirms that the requested resource was not found. Fix the URL or deployment before changing CSS or JavaScript.
3. Serve the correct PNG MIME type
A PNG response should declare Content-Type: image/png. The PNG specification’s web-server guidance calls this the first requirement for proper support, and image/x-png is obsolete. See HTTP media types and MDN’s MIME type reference.
Check the header:
curl -I https://example.com/images/logo.png
Look for:
HTTP/2 200
content-type: image/png
Examples of server configuration:
Apache
AddType image/png .png
Nginx
http {
include mime.types;
types {
image/png png;
}
}
Node.js
import http from "node:http";
import fs from "node:fs";
http.createServer((req, res) => {
if (req.url === "/logo.png") {
const file = fs.readFileSync("./public/logo.png");
res.writeHead(200, { "Content-Type": "image/png" });
res.end(file);
return;
}
res.writeHead(404);
res.end("Not found");
}).listen(3000);
If the server returns text/html, the response may be an error page or an SPA fallback rather than the PNG. Fix the route or static-file middleware.
4. Check CSP, CORS, and mixed content
Content Security Policy
A Content-Security-Policy can block a valid image URL. The policy’s img-src directive controls image sources; if it is absent, default-src applies. The W3C specification says the user agent must treat a disallowed image as a fatal network error and obtain no resource. Read the W3C Content Security Policy specification.
Content-Security-Policy: default-src 'self'; img-src 'self' https://cdn.example.com data:;
Add the actual image host, including the CDN origin, then reload with DevTools open. Do not add a broad wildcard unless you understand the security impact.
CORS
Normal <img> display can work cross-origin without JavaScript access to the pixels. CORS becomes relevant when canvas, scripts, credentials, or a storage policy are involved. If a cross-origin image is drawn to a canvas, return an appropriate header and set the element attribute before loading:
<img src="https://cdn.example.com/photo.png" crossorigin="anonymous" alt="...">
Configure the object store or CDN to allow the requesting origin when your use case requires it. AWS lists CORS and origin configuration among CloudFront image-load failure causes; see AWS CloudFront troubleshooting.
Mixed content
An HTTPS page must not request an HTTP image. Change the asset URL and origin to HTTPS, and check redirects: an HTTP-to-HTTPS redirect can still fail if the initial request is blocked by the browser.
5. Repair CDN and object-storage delivery
When the origin works but the public URL fails, compare the origin URL with the CDN URL. Check:
- The object exists in the bucket and the key exactly matches the URL.
- The CDN identity or origin access control can read the object.
- Public access, signed URLs, and expiration rules match the intended audience.
- Cache behavior forwards the query strings, cookies, or headers your authorization scheme needs.
- The cached response has
Content-Type: image/png. AWS specifically says the origin metadata must beimage/png. - Redirects point to the expected host and protocol.
After changing metadata or permissions, purge the affected CDN path or wait for its TTL. Test with a cache-busting query string only as a diagnostic; do not rely on it as the permanent fix.
6. Rule out browser cache, extensions, and local security software
If the same URL returns 200 with the correct headers for other users, test locally:
- Open a private window.
- Disable extensions that block ads, trackers, scripts, or remote media.
- Clear the site’s cache and storage.
- Try another browser and network.
- Check antivirus, endpoint protection, and corporate proxy logs.
Mozilla includes cache, extensions, security software, and modified browser settings in its image troubleshooting guidance. If only one user is affected, collect the Console and Network output before changing server configuration.
7. Verify that the bytes are really a PNG
A file named .png can contain HTML, a truncated upload, or another format. Download it and inspect its signature:
curl -L https://example.com/images/logo.png -o /tmp/logo.png
file /tmp/logo.png
xxd -l 8 /tmp/logo.png
A valid PNG starts with the eight-byte signature 89 50 4e 47 0d 0a 1a 0a. If file reports HTML, inspect the downloaded body for an error page, login redirect, or framework fallback. If the file is truncated, regenerate or re-upload it and verify the upload’s checksum.
8. HTML and CSS examples that work
HTML image
<img
src="/assets/hero.png"
width="1200"
height="630"
alt="Product dashboard"
decoding="async"
>
CSS background
.hero {
background-image: url("/assets/hero.png");
background-size: cover;
background-position: center;
}
CSS images appear in the Network panel too, but they will not show an HTML broken-image icon. Confirm the computed style contains the expected URL and that no later rule sets display: none, opacity: 0, or a zero-sized container.
9. Troubleshooting by symptom
| Symptom | Cause to confirm | Fix |
|---|---|---|
| Works locally, fails after deployment | Case-sensitive path, file omitted from build, or host rewrite | Inspect the production URL and deployment artifact |
| Broken icon with 404 | Wrong relative path or filename | Correct src and capitalization |
| 403 from CDN | Origin access, bucket policy, signed URL, or expired token | Grant the CDN access or issue a valid URL |
| PNG downloads instead of displaying | Incorrect Content-Type or Content-Disposition: attachment |
Return image/png and remove attachment disposition when inline display is intended |
| Console reports CSP violation | Image host absent from img-src |
Add the exact origin to the policy |
| Canvas becomes tainted | Cross-origin image lacks the required CORS response | Configure CORS and use crossorigin before loading |
| Only Safari, Chrome, or one account fails | Cache, extension, privacy tool, or stale service worker | Test privately, unregister the service worker, and compare requests |
| Image is a white or blank rectangle | CSS sizing, transparent pixels, lazy-load trigger, or decode failure | Inspect dimensions, computed styles, and the Console; force a visible test background |
10. Performance and reliability considerations
- Serve images from a nearby CDN, but preserve correct metadata when objects are cached.
- Set explicit
widthandheightto reduce layout shifts. - Use responsive formats and sizes where appropriate, while keeping a valid PNG fallback when transparency or lossless pixels are required.
- Use long cache lifetimes with hashed filenames; purge or rename files when content changes.
- Keep origin permissions private when possible and grant only the CDN identity the access it needs.
- Monitor image request status codes separately from HTML errors. A 200 HTML fallback is still a broken image.
- For critical assets, test a cold cache and a warm cache, from more than one browser and region.
11. A repeatable debugging checklist
- Copy the exact requested URL from Network.
- Open it directly.
- Check 404 versus 403 versus 200.
- Verify
Content-Type: image/png. - Confirm the bytes begin with the PNG signature.
- Read Console messages for CSP, CORS, and mixed content.
- Compare origin and CDN responses.
- Check filename case and deployment output.
- Purge stale cache and retry.
- Retest in another browser or private window.
12. Or skip the browser setup
If you need a dependable screenshot of a page while diagnosing how it renders, ScreenshotNeo provides a single API request that returns PNG, JPEG, WebP, or PDF. The request accepts the URL and can capture a full page or a selected element; the ScreenshotNeo documentation lists all options.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. An MCP server lets Claude, Cursor, and other MCP clients take screenshots with take_screenshot, inspect pages with get_page_info, and create PDFs with capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
13. FAQ
Why does the PNG URL work when I paste it into a tab but not in my page?
Compare the page request with the direct request. CSP, mixed content, credentials, redirects, or a different referrer can affect the embedded request even when the URL itself opens.
Can a 200 response still be broken?
Yes. A 200 response may contain HTML, invalid bytes, an incorrect MIME type, or a transparent image that appears blank. Inspect the headers and downloaded bytes.
Does PNG need CORS to display?
Not for ordinary cross-origin display in an <img>. CORS is needed for operations such as reading the pixels through canvas or requests made with script and credentials.
Should I disable CSP to make the image load?
No. Keep the policy and add only the specific image or CDN origin required by the page.
Why did a cache purge not fix it?
The origin may still return the wrong metadata or permissions, multiple CDN paths may be cached, or a service worker may serve its own response. Check the origin, CDN, and browser caches separately.


