Why Images Fail to Load on Some Websites and How to Fix Them
Find the cause of broken images by checking scope, browser settings, network errors, HTTPS, CSP, CDN caching and lazy loading—with fixes for visitors and site owners.
A broken image is a symptom, not a diagnosis. The same empty frame can come from a bad URL, an unavailable server, a browser extension, privacy or security software, a network failure, HTTPS mixed content, Content Security Policy, CDN caching, or lazy-loading code.
Start by narrowing the scope:
- One image: check its URL, file, response and permissions.
- One website in one browser: check extensions, site data, privacy settings and browser security controls.
- One website in several browsers: investigate the website, CDN or image host.
- Many websites: investigate connectivity, VPN, firewall and security software.
Use the narrowest reversible test that matches what you see. A private window and a second browser quickly separate many browser-side problems from site-side problems.
Fix a broken image as a visitor
- Reload the page and see whether one image or every image fails.
- Open the same page in a private window. If it works there, review extensions and site-specific data.
- Try another browser. A browser-specific failure points to permissions, tracking controls, extensions, cached data or security settings.
- If several sites fail, check the connection and whether a VPN, firewall or security product is interrupting requests.
- If one site fails in several browsers, send the operator the page URL, image URL if visible, browser and device, and approximate time.
Do not disable antivirus or other security protection wholesale. If a security product blocks one image, inspect its site-specific controls or follow that product’s documentation.
Use a private window and another browser
A private window starts with a cleaner extension and cookie state. If the image appears, disable extensions one at a time, then clear data for the affected site. Mozilla’s troubleshooting guidance covers cache, extensions, settings and security software as possible causes: Mozilla Support.
Check browser errors
Open Developer Tools, select the Network tab, reload, and filter by Img. Record the request URL, status code, response headers and console message. Chrome documents connection resets, timeouts, refused connections and network changes among common page-loading failures: Chrome Help.
Diagnose the failed image request
For a site owner, the request itself provides the fastest evidence. In Developer Tools:
- Open Network, enable “Preserve log,” reload, and select the failed image.
- Confirm the final request URL after redirects.
- Check the status:
404usually means a missing path,403suggests access control,5xxindicates a server or upstream failure, and a blocked or cancelled request points to browser policy, an extension or connectivity. - Read the Console for mixed-content, CSP, CORS or certificate messages.
- Compare the response in a private window and from another network when appropriate.
Test an image URL from the command line
These checks test delivery without rendering a page. Replace the URL with the exact failed request.
curl -I -L "https://cdn.example.com/images/photo.webp"
Look for a successful status, a usable Content-Type such as image/jpeg or image/webp, and a certificate-valid HTTPS URL.
python - <<'PY'
import requests
url = "https://cdn.example.com/images/photo.webp"
r = requests.get(url, timeout=30, allow_redirects=True)
print(r.status_code, r.url, r.headers.get("content-type"))
r.raise_for_status()
open("downloaded-image", "wb").write(r.content)
PY
node - <<'JS'
const url = 'https://cdn.example.com/images/photo.webp';
const res = await fetch(url, { redirect: 'follow' });
console.log(res.status, res.url, res.headers.get('content-type'));
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('downloaded-image', data);
JS
Common causes and fixes for site owners
1. The URL or file is wrong
Malformed paths, wrong filename case, missing files and incorrect relative paths produce broken images. Verify the rendered src value, then retrieve that exact URL. Check path and filename case on case-sensitive hosting, confirm the file exists, and make sure the intended audience can access it. Mozilla specifically lists malformed image URL paths as a cause of missing images.
2. HTTPS mixed content
An HTTPS page that requests an HTTP image can be upgraded or blocked by browser behavior. Serve the image over HTTPS, update stored URLs and redirects, and inspect the console. See MDN’s mixed-content guidance and Cloudflare’s mixed-content troubleshooting.
3. Content Security Policy blocks the image
A restrictive Content Security Policy must allow the image’s origin in the applicable img-src directive (or in default-src when no image-specific directive exists). Add only the required origin, deploy the policy, and verify the console message. MDN explains how CSP resource directives control browser fetches: Content Security Policy.
Content-Security-Policy: default-src 'self'; img-src 'self' https://cdn.example.com data:;
4. CDN or optimization behavior serves stale or altered content
A CDN can cache a missing response, apply an incorrect transformation, or interfere with a request. Purge the affected image URL, then retest in a private tab. If you use Cloudflare, temporarily pause the proxy or disable Rocket Loader one at a time as a diagnostic test, then restore normal settings after identifying the cause. Cloudflare documents these isolation steps in Troubleshoot missing images.
Also compare the origin response with the CDN response, check cache status headers, and confirm that content negotiation is not returning an unsupported format.
5. Lazy loading delays or omits the request
Lazy loading should not defer content likely to be visible immediately. Make sure the image is requested when it enters the viewport and that the rendered image URL appears in the img src attribute when crawler visibility matters. Google’s guidance covers lazy-loaded content and rendered image URLs: Fix lazy-loaded website content.
<img src="/images/hero.webp" alt="Product dashboard" loading="eager" width="1200" height="675">
Use loading="lazy" for below-the-fold images, but keep the main visible image discoverable and available without waiting for a scroll event.
6. Access control, authentication or hotlink protection
An image may work for logged-in users but return 401 or 403 to other visitors, crawlers or a CDN. Check signed URL expiry, cookie requirements, referer rules and authorization headers. Make the asset public when it is intended to be public, or ensure every intended client receives the required credentials.
7. Certificate, DNS or connection failures
Expired certificates, DNS errors, refused connections and timeouts prevent the browser from receiving an image at all. Compare the image host in another browser and network, inspect the certificate, and check DNS and server logs. Chrome’s error guidance is useful for distinguishing connection resets, timeouts and refused connections.
A practical decision tree
| Observation | Most likely area | Next check |
|---|---|---|
| One image fails everywhere | URL, file, permissions or origin server | Request the exact URL and inspect status and headers |
| All images fail in one browser | Extension, privacy setting, cache or security software | Private window, extensions, site data and another browser |
| One site fails in several browsers | Website, CDN, CSP, HTTPS or image host | Console, failed request, CDN and origin comparison |
| Many sites fail | Network, VPN, firewall or security software | Another network and security-product logs |
| Only images below the fold fail | Lazy-loading implementation | Viewport behavior and rendered img src |
Troubleshooting checklist
- Record the page URL, image URL, browser, device and time.
- Reproduce in a private window and a second browser.
- Inspect the failed request and console message.
- Verify URL spelling, path case, redirects and file existence.
- Serve the page and image over HTTPS.
- Allow the image origin in CSP.
- Check authentication, signed URLs and hotlink rules.
- Compare CDN and origin responses; purge the affected object when appropriate.
- Review lazy-loading behavior for visible and crawler-important images.
- Restore temporary CDN or optimization changes after isolating the cause.
Performance and reliability considerations
Use correctly sized responsive images, modern formats where supported, explicit width and height, and caching with an intentional invalidation strategy. Keep the critical visible image available early, while lazy-loading lower content. Monitor image requests separately from HTML so a page that renders text does not hide an image delivery outage.
When diagnosing CDN changes, alter one setting at a time and retest from a private window. This preserves a useful comparison and avoids leaving an emergency configuration in place.
Or skip the browser setup
ScreenshotNeo captures a page with one API request. Before the capture it accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server gives Claude, Cursor and other MCP clients take_screenshot, get_page_info and capture_pdf tools.
See the ScreenshotNeo API documentation for all options, including full-page and element capture, custom CSS and JavaScript, waits, request blocking, headers, cookies, user agents, timezone and geolocation, resizing, caching, signed links, asynchronous jobs, bulk capture and usage data.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
There is a free plan with 1,000 screenshots a month and no card. Paid plans start at $5 for 3,000 screenshots, and every feature is included on every plan. Create a free ScreenshotNeo account.
FAQ
Why does an image load after I refresh?
A transient connection, origin or CDN failure may have cleared, or a cached response may have changed. Inspect the request while the problem is present.
Can browser cache alone cause a broken image?
Yes. Site-specific cached data can preserve an outdated URL or response. A private window is a quick test before clearing broader browser data.
Does changing image format fix every failure?
No. Format conversion cannot fix a missing URL, blocked request, CSP violation, authentication failure or unavailable server.
Why can text load while images fail?
HTML and images can come from different hosts, policies, caches or credentials. Inspect the image request rather than assuming the whole page is healthy.
How do I prove a lazy-loaded image is discoverable?
Inspect the rendered DOM and confirm the intended URL is present in the img src attribute, then verify the request occurs as the image enters the viewport.


