Why does an image on my website show a broken icon?

Updated · Check Before Publish

A broken image icon means the browser requested the image and could not use the response: a missing file (404), a refused request (403), a blocked insecure address, or a web page returned instead of an image. In developer tools, filter the Network panel to images and read the status and content type of each failing request.

The short version

  • The HTML Standard says the status code is ignored when deciding whether an image is valid: what counts is whether the bytes are a supported image. So a 404 that carries real image bytes can still display, and a 200 that carries HTML does not.
  • The icon itself is up to the browser: the standard says it is shown “optionally”. If the image has non-empty alt text, that text is shown instead of the picture.
  • An alt="" image that fails to load shows nothing: visual browsers hide the broken icon when alt is empty.
  • A CSS background-image that fails to load shows no icon and no alt text; the browser treats it as none.
  • Browsers upgrade an http:// image on an https page, and block some cases (see the table).

Causes, and how each shows up

CauseWhat you see in the Network panelNotes from the official pages
The file is missing or movedStatus 404MDN: common causes of a 404 are mistyped URLs or files “moved or deleted without redirection”.
The URL returns a page, not an imageStatus 200, but the content type is text/html instead of an image typeThe HTML Standard: image data that is not in a supported format sets the request to broken. The status is ignored.
The path differs in letter caseStatus 404 for /Img/Photo.PNG when the file is photo.pngRFC 3986: apart from scheme and host, URL parts are “assumed to be case-sensitive”. Whether a server maps a path to a file case-sensitively depends on the server.
An insecure image on an https pageA console message about mixed contentMDN: browsers auto-upgrade img from http to https, “but not when setting resources with srcset or <picture>”, and block it if the host is an IP address. If the https address doesn't serve the file, it fails.
Another site's rules refuse the request (hotlink protection)Status 403 on an image from another siteCloudflare's hotlink protection “denies access to requests when the HTTP referer does not include your website domain name (and is not blank)”. The page does not say what the visitor sees.
A Content Security Policy or cross-origin policy blocks itThe request is marked blocked, with a console messageMDN: img-src limits valid image sources; CORS and Cross-Origin-Resource-Policy can block cross-origin images.
A srcset that lists no usable fileNo image request at allMDN: with w descriptors, src is not considered. Google recommends always giving a fallback src.

An image that has not loaded yet is not necessarily broken: MDN says lazy-loaded images are not loaded until they intersect a visible part of the page.

Find it in your browser

  1. Open developer tools, choose the Network panel and reload the page.
  2. Filter to images (Chrome has an Img button) and look for rows with a red status or an odd status.
  3. Read the Status and the Type columns. Chrome's reference describes Type as “The MIME type of the requested resource”. A 200 whose type is text/html is a web page served in place of an image.
  4. Check the Console for mixed-content and CORS messages.

Find them for a whole page

Paste the page address. The checker lists every image the HTML refers to and reports the ones that fail to load, redirect, or load over http://.

Opens the Broken Link Checker and runs it. Free, no account. The address is not stored and never goes into the URL bar.

What we tested

On 2026-10-13 we built a test page with seven <img> elements and ran the live Broken Link Checker on it. The test site is a preview that search engines are told not to index and is not part of this site.

The imageWhat the checker reported
A working PNGCounted as answered normally.
A file that does not exist“Broken image (404)”: Fix before publishing.
The same file name in a different letter case (on this host, a 404)“Broken image (404)”: Fix before publishing.
An image on another site that answers 404“Broken image (404)”: Fix before publishing.
An image on another site that answers 403“Image answered 403 to our checker”: Review. “It may work for visitors — open it in a browser to confirm.”
The same working PNG requested as http:// on an https page“Image loaded over http:// on an https page”: Review.
A web page (status 200, text/html) used as the imageNot reported. The summary read “2 of 7 links and resources answered normally”: the working PNG and this one.

So the checker catches missing files, refused requests and insecure images, but it judges an image by its status code, not by what the response contains. A 200 that is really HTML slips through; the Network panel's Type column catches it. For og:image the Open Graph Checker does check the content type: it reported “og:image is not an image (text/html; charset=utf-8)” in the same situation.

What this can't tell you

It reads the HTML, so images added by JavaScript and CSS backgrounds are not part of the check. It fetches from our server: a request that is refused for us may work for a visitor, and the reverse. It does not say why a request failed, only what came back.

Related: Mixed content and Open Graph image not showing.

Sources

We read these official pages on 2026-10-13.

Fixed this one? Before you send people to the page, run the full pre-publish check for everything else: indexing signals, link preview, broken links, alt text, structured data and HTTPS in one pass.