Images Not Loading on My Website? Nine Causes, Checked in Order

VenbitThe Venbit TeamSeptember 4, 20269 min read

The short answer

Right-click a missing image, choose Inspect, and open the Network tab. A 404 means the file isn't where the page says it is, which is the most common cause by far. A 403 means something is refusing to serve it. No request at all usually means lazy loading or an ad blocker.

Key takeaways

  • The browser already knows why. The Network tab in DevTools gives you a status code that names the cause.
  • A 404 after a site move or a domain change is the single most common reason images stop loading.
  • Mixed content, hotlink protection and file permissions all show up as a 403 or a blocked request, not a 404.
  • If the image loads when you paste its URL directly but not on the page, suspect lazy loading, caching or an extension.
  • Check on a second device and a second network before you change anything on the server.

Images stop loading on a website most often because a file's address changed and the page is still asking for the old one, usually after a move, a rename, or a redesign. That single cause explains more broken images than everything else on this page combined. When it isn't that, the usual suspects are mixed content on an https site, hotlink protection, file permissions, or an ad blocker on the visitor's own browser. Resist the urge to re-upload things before you know which one you have. The browser already knows: right-click a missing image, choose Inspect, open the Network tab and reload, and a status code appears beside every file the page asked for. The nine causes below run most likely to least.

Images not loading on a website: read the status code first

What you seeWhat it usually meansGo to
404 Not FoundNothing is at that addressCauses 1 and 5
403 ForbiddenIt exists, something refuses to serve itCauses 4 and 6
Blocked, plus a mixed content warningThe page is https, the image is httpCause 2
No request in the list at allA script or extension stopped itCauses 3 and 8
Times outThe file is enormous, or the host is downCauses 5 and 9
Fine for you, broken for everyone elseYou are seeing a cached copyCause 7
What the browser is telling you

1. A broken path after a move, a rename, or a redesign

This is the cause more often than every other one on the list put together. Something changed the address of the file and the page still asks for the old one. Moving from staging to live, changing domains, switching hosts, renaming a folder, cleaning out the media library, restoring a partial backup: all of them do it.

The check: a 404, and the address contains something that shouldn't be there. An old domain. The word staging. A folder that no longer exists. Two slashes in a row.

The fix: for one or two images, re-insert them from the media library so the page picks up the current address. For a whole site's worth, use a search-and-replace tool such as Better Search Replace on WordPress, which rewrites the old paths in one pass and offers a dry run first. Back up before you run it.

2. Mixed content on an https site

Your site loads over https but an image is still linked over plain http. Browsers treat that as mixed content. Chrome and the other major browsers now try to upgrade the request to https automatically, and if the upgrade fails, the image is blocked rather than shown. The symptom is an image that worked fine and vanished the day you installed an SSL certificate.

The check: the Console tab prints an explicit mixed content warning naming the file. Worth knowing: a plain img tag gets the automatic upgrade, but an image set through srcset or a picture element does not. Those are blocked outright, which is why one responsive image can vanish while the one beside it is fine.

The fix: change the links from http to https. Those addresses are usually baked into the database from before the certificate, so the same search-and-replace from cause 1 handles it. If the image lives on somebody else's server and that server has no https, download it and host it yourself.

3. A lazy-load or CDN plugin that isn't doing its job

Lazy loading holds images back until they're about to scroll into view. Browsers do it natively now with a loading="lazy" attribute and it's reliable. The trouble is plugins that do it in JavaScript instead. If another script on the page throws an error first, the images never get told to load, and you're left with grey placeholders.

The check: view the page source and look at the img tag. If the real address is sitting in a data-src attribute and the src is a placeholder, a script is supposed to swap them in and hasn't. Then look in the Console for a red JavaScript error. One broken script takes out everything after it.

The fix: turn off lazy loading in the plugin and reload. If the images come back, you've found it. Leave it off and rely on native lazy loading, or hand the broken script off to whoever manages your site to track down. Same logic for image CDN plugins: switch the CDN off, and if the images return, it's misconfigured.

Hotlink protection serves an image only when the request comes from your own domain, so other sites can't embed your photos and spend your bandwidth. Sensible, and it regularly locks out the wrong people. Forget that your site runs on a subdomain, or that your CDN requests from a different hostname, and your own images start returning 403.

The check: a 403 on the page, but the image loads fine pasted into a blank tab. That's the signature, because opening it directly sends no referring page.

The fix: turn it off, or add the missing hostnames. On Cloudflare the toggle sits under Security, then Settings, and it only covers GIF, ICO, JPG, JPEG and PNG. On cPanel hosts it's Hotlink Protection under Security. Cloudflare's docs also warn it stops your images appearing on Google Images, Pinterest and Facebook.

5. The file is too big, or it's a format the browser won't display

Two problems, same shrug. First, size: if a file never finished uploading because it exceeded the server's limit, there's nothing at the address and you get a 404. WordPress prints the maximum upload size right in the media uploader, and it inherits that from PHP, whose default is a mere 2 MB. Plenty of phone photos are bigger than that.

Second, format. Browsers display JPEG, PNG, GIF, WebP, AVIF and SVG. HEIC, which is what an iPhone shoots by default, works only in Safari. TIFF is Safari-only too, and PSD and camera raw aren't web formats at all. The trap on WordPress is that it accepts a .heic upload happily and only converts it to JPEG if the server has the right image library. On a host that doesn't, the file sits in the media library looking normal and shows up for nobody outside Safari.

The check: look at the file extension in the URL. If it's .heic, .tif, .psd or .raw, that's your answer.

The fix: convert to JPEG or WebP before uploading. On an iPhone, stop it at the source: Settings, Camera, Formats, Most Compatible, and it shoots JPEG from then on. For upload limits, shrink the image, which you should be doing anyway, or ask your host to raise the ceiling.

6. File or folder permissions on the server

Every file on a Linux server carries permissions saying who may read it. If an upload folder ends up with the wrong ones, usually after a manual FTP transfer or a restore from an old backup, the server refuses to hand the files to visitors even though you can see them sitting in your file manager.

The check: 403 on the image, no hotlink protection enabled, and the file visibly exists when you look in FTP or your host's file manager.

The fix: 644 for files and 755 for directories is what WordPress itself recommends, and most FTP clients set that from a right-click menu with an option to apply it to everything in a folder. If those numbers mean nothing to you, email your host. They deal with it daily.

7. A caching layer showing an old version of the page

There can be four caches between your database and a visitor's eyes: a caching plugin, the host's server cache, a CDN, and the browser. Any one can keep serving the page from before you fixed something. This is why images look broken to your customer and perfect to you, or the reverse.

The check: open the page in a private window, or on your phone with wi-fi off. A different result means you're chasing a cache, not a bug.

The fix: clear them in order, closest to the visitor last. Plugin cache, host cache, CDN purge, hard reload, then check again in a private window. Skipping to the CDN purge and declaring victory is how this comes back an hour later.

8. An ad blocker or extension on the visitor's own browser

Content blockers filter on file names and paths, not on what's in the image. EasyList, the default filter list behind most blockers, carries well over a hundred rules aimed at images alone, matching paths like /ads/images/ and /banner-ads/. Any ordinary business photo that happens to sit in a similarly named folder gets caught in the crossfire, which is why a completely innocent picture can vanish for a chunk of your visitors with no error anywhere for you to find.

The check: load the page in a private window with extensions disabled, or a different browser. If the images appear there, an extension is doing it. In Chrome's Network tab the giveaway is a status of ERR_BLOCKED_BY_CLIENT, which means the request never left the browser.

The fix: rename the files and the folder. Avoid ad, ads, banner, sponsor, promo and popup in image names and paths. Don't ask visitors to turn off their blockers. They won't.

9. A host outage or a DNS problem

Last because it's rare, and because the symptom is usually the whole site being down rather than the images alone. The exception: if your images come from a separate CDN hostname or a storage bucket, that service can fail on its own while your pages keep loading. A working site with holes in it.

The check: the URL times out in a fresh tab and fails on a second network too, such as your phone on cellular data. Then look at your host's status page and your CDN provider's.

The fix: none from your end beyond opening a ticket, which is why the useful move is knowing within minutes rather than hearing it from a customer three days later. Uptime monitoring is standard on any maintenance plan worth paying for, and it costs less than one lost afternoon.

Stopping it from happening again

  1. 1After any migration, spot-check five interior pages. Not the homepage. Interior pages are where broken images hide.
  2. 2Convert phone photos to JPEG before they go near the site.
  3. 3Keep image file names boring and descriptive. Good for search, and it keeps ad blockers out of your business.

Work down all nine and what's left is narrow enough that someone with server access finds it fast. We're Venbit, in Mill Creek north of Seattle, and this is included in the maintenance plans we run for clients across the Puget Sound and remotely, from $99 a month. If it's blurry images rather than missing ones, start with why website images look blurry or broken.

More website answers

Every question in this series, from Website Problems, Solved.

Symptoms & emergencies22
What happens if...15
Cost & pricing9
Plans & hiring11
Ownership & switching15
Platform-specific7
Seattle & local2

Common questions

Questions, answered straight.

Straight answers about website fixes for your business. If yours isn't here, ask us directly and we'll give it to you straight.

Ask the team

Because the media library reads files straight off the server while a page requests them over the web. The gap between those two is usually a wrong path, hotlink protection, or file permissions. Copy the image address from the page, paste it into a new tab, and see whether it loads. That narrows it immediately.

Your pages now load over https but the image links are still saved as http, which browsers treat as mixed content and block. Check the Console tab in developer tools for a mixed content warning naming the file. The fix is a database search-and-replace changing http to https across the old image URLs.

Yes, and it catches people out constantly. Content blockers match on file names and folder paths, so an image called banner-ad.jpg or anything in a folder named /ads/ can be blocked before the request is made. Rename the file and the folder to something descriptive and the problem goes away for good.

Safari is the only browser that displays HEIC, so the file uploads fine and then shows nothing to anyone on Chrome, Firefox or Edge. WordPress will convert HEIC to JPEG on upload, but only if the server has the right image library, so don't count on it. Convert to JPEG before uploading, or set the iPhone camera format to Most Compatible.

Open the page in a private window with extensions off, then on a phone with wi-fi switched off so you're on a different network. If the images appear in either test, the site is fine and the problem is a cache or an extension on the machine you were using. If they're missing everywhere, it's the site.

Free 30-minute strategy call

Let's talk about your project.

Tell us what you need and we'll give you an honest read on the project, the timeline, and what it takes, before you spend a dollar. Based in Seattle, working across the Puget Sound.

4.8 on Google 5.0 on Yelp