How to Fix and Handle Broken Images

Treehouse

December 24, 2013

-

6 min read

Learn

A broken image is one of the most common problems you’ll encounter when building websites — and one of the easiest to fix once you know where to look. This guide covers the most common causes, how to diagnose them using your browser’s built-in tools, how to prevent them from happening in the first place, and how to handle them gracefully when they do.


What Causes a Broken Image?

When a browser can’t load an image, it displays a broken image icon in its place. This happens for one of a few reasons:

  • The image file doesn’t exist at the path specified
  • The filename or file extension is incorrect
  • The file path in your HTML is wrong
  • The file has incorrect permissions on the server
  • A CDN or external host is unavailable or the URL has changed
  • The image is set to load lazily but never enters the viewport due to a layout issue

The fastest way to identify which of these is the problem is to check your browser’s DevTools before doing anything else.


Step 1: Diagnose with Browser DevTools

Open DevTools in Chrome or Firefox with F12 (Windows/Linux) or Cmd + Option + I (Mac). Go to the Network tab, reload the page, and filter by Img. Find the broken image in the list and check its status code:

  • 404 — the file doesn’t exist at that path, or the path is wrong
  • 403 — the file exists but the server is blocking access (a permissions issue)
  • 200 — the file loaded successfully, which means the problem is likely a layout or lazy loading issue rather than a missing file

The Console tab will also log errors for broken images directly, which can be quicker to spot at a glance.


Step 2: Verify the File Exists

Before adjusting any code, confirm the image file is actually where you think it is. Open your project folder and navigate to the expected location. It’s a common mistake to think a file has been saved or uploaded when it hasn’t.

While you’re there, check the filename carefully:

  • cupcake.jpg and cupcake.jpeg are different files
  • featured-image.jpg and featured_image.jpg are different files
  • Filenames are case-sensitive on most servers — Cupcake.jpg and cupcake.jpg are not the same

Step 3: Check the File Path

If the file exists but the image is still broken, the path in your HTML is likely wrong. There are two types of file paths: relative and absolute.

Relative Paths

A relative path points to a file in relation to the current HTML file’s location. This is what you’ll use most of the time.

html

<img src="img/cupcake.jpg" alt="A chocolate cupcake on a white plate.">

This tells the browser: starting from where this HTML file lives, go into a folder called img and find cupcake.jpg.

If your CSS file needs to reference the same image, the path must be relative to the CSS file’s location — not the HTML file. To move up one directory level, use ..:

css

background-image: url('../img/cupcake.jpg');

Absolute Paths

An absolute path includes the full URL. Use this only when the image is hosted on a different domain, such as a CDN you control:

html

<img src="https://cdn.yoursite.com/img/cupcake.jpg" alt="A chocolate cupcake on a white plate.">

Never use a local file path — paths beginning with file:/// or containing C:\ or My Documents only work on your own machine. They will break for every other visitor to your site.

Avoid hotlinking images from other websites. Aside from potential copyright issues, you have no control over those images — the owner can remove them, rename them, or replace them with something else entirely.


Step 4: Fix File Permissions

If DevTools shows a 403 status for your image, the file exists on the server but something is blocking access to it. This is a permissions issue.

The correct permission for a publicly accessible image file is typically 644 — readable by everyone, writable only by the owner. You can check and update permissions using whatever tool you use to manage your server:

  • FTP clients (such as FileZilla or Transmit): right-click the file and look for a “File Permissions” or “Get Info” option
  • SSH: run chmod 644 filename.jpg from the command line
  • Hosting control panels: most cPanel or Plesk interfaces have a file manager with a permissions editor

Step 5: Handle Broken Images Gracefully with JavaScript

Prevention is the goal, but images can still fail at runtime — a CDN goes down, a user-generated image gets deleted, a URL changes after deploy. Handling these failures gracefully means the rest of your page keeps working and users see something useful instead of a broken icon.

The onerror event

The <img> element fires an error event when it fails to load. You can use this to swap in a fallback:

html

<img src="img/cupcake.jpg" alt="A chocolate cupcake on a white plate." id="hero-image">

js

const img = document.querySelector('#hero-image');

img.addEventListener('error', () => {
  img.src = 'img/fallback.jpg';
});

Managing fallbacks at scale with a data attribute

If you have many images across a page, hardcoding fallback paths in JavaScript doesn’t scale well. A cleaner pattern is to store the fallback path in a data- attribute on each image, then handle them all with one listener:

html

<img src="img/cupcake.jpg" data-fallback="img/fallback.jpg" alt="A chocolate cupcake on a white plate.">
<img src="img/muffin.jpg" data-fallback="img/fallback.jpg" alt="A blueberry muffin on a wooden board.">

js

document.querySelectorAll('img[data-fallback]').forEach(img => {
  img.addEventListener('error', () => {
    const fallback = img.dataset.fallback;
    if (img.src !== fallback) {
      img.src = fallback;
    }
  });
});

The if (img.src !== fallback) check prevents an infinite loop in the unlikely case that the fallback image itself also fails to load.


A Note on Alt Text

The alt attribute is your last line of defence when an image cannot be recovered. Write it as if the image will fail — because sometimes it will.

A good alt attribute describes what the image shows and why it’s there:

html

<!-- Weak: generic and unhelpful -->
<img src="img/cupcake.jpg" alt="image">

<!-- Better: describes the content -->
<img src="img/cupcake.jpg" alt="A chocolate cupcake with vanilla frosting on a white plate.">

For decorative images that convey no information, use an empty alt attribute (alt="") so screen readers skip them. Never omit the attribute entirely — that causes screen readers to announce the filename instead.


Summary

When you encounter a broken image, work through these steps in order:

  1. Open DevTools > Network tab and check the HTTP status of the image
  2. Confirm the file actually exists at the expected path
  3. Verify the filename, extension, and case are correct
  4. Check whether the path is relative or absolute and that it’s correct for the file doing the referencing
  5. If the status is 403, check file permissions on the server
  6. For runtime failures, use the error event with a fallback image and a data-fallback pattern for scale
  7. Make sure every image has a descriptive alt attribute

19 Responses to “How to Fix and Handle Broken Images”

  1. Brett on May 6, 2018 at 5:07 am said:

    I couldn’t figure this out for so long and I didn’t realize I was calling my background image from inside the css file inside the css directory! Two dots to make the path go back out made all the difference. Any problems I run into always seem to be the easiest solutions. I’m an absolute beginner and this page made my day.

  2. Thanks for your post. I found this only worked for me. I really appreciate this.

  3. Hiren Kukadiya on May 22, 2017 at 6:55 am said:

    $(window).load(function() {
    $(“img”).each(function(){
    var image = $(this);
    if(image.context.naturalWidth == 0 || image.readyState == ‘uninitialized’){
    $(image).unbind(“error”).hide();
    }
    });
    });

  4. Deanna on June 15, 2016 at 1:22 pm said:

    Hello, I am trying to copy and paste from chrome into outlook after long hours of labor on a very difficult responsive email…long story short it only retains links if I do it from that browser…however now of course there is another issue as there always is. My images will not copy and paste along with it via Chrome only-the one that I need. Is there an answer to this- all my links are correct….is it a chrome issue that can be fixed?

  5. Could use javascript to add a default placeholder for all broken images?

    $(‘img’).on(‘error’, function (){
    $(this).prop(‘src’, ‘img/broken-image.png’);
    });

  6. This was really helpful and educative. Sending you good energy from Transylvania.

  7. Douglas Barnes on February 5, 2016 at 4:20 am said:

    I just dealt with a case where I couldn’t see the images on a site because of the permission settings. I changed all the settings to 744 via the terminal to no effect. They only behaved when I changed the settings manually on my local machine, then uploaded the images again. Gremlins are suspected.

  8. Thanks so much! I’m learning coding and I’m a total beginner and I was stuck with a broken image for the past 5 days. Your article helped me finally fix the problem!!

  9. When i open Yahoo. the front page shows a bunch of broken pictures and i dont know why. ive tried disabling ad block, restarting, deleting history and cookies.

    its just my yahoo. nothing else, any idea?

  10. this is complicated as balls

  11. Nick are you sure its perfect solution? i did’t face this issue yet may be i face issue in feature so i want to just confirm it.
    Thanks for sharing

  12. Hi,

    I published a website last week and figured it out after realizing that the folder holding my photos was labeled “IMG” but I was referencing a non-existent folder named “img”. Chrome loaded the photos anyway, but Safari didn’t! Interesting!

  13. Good content here Nick! Love your Treehouse videos as well. I’ve tried to get rid of most of my bad habits when it comes to broken images. Most of the time I upload the file to the wrong directory once going live!

    This also happens when I have clients send me pictures with uppercase extensions (like .JPG) and I link them lowercase (like .jpg). That can be annoying as well!

  14. Thanks Nick. This can come in handy.

    Cheers,
    Carmon

  15. Chris Akers on December 25, 2013 at 2:39 am said:

    Thanks, Nick!

    You discussed document-relative URLs here but I much prefer root-relative URLs! So instead of:
    “img/cupcake.jpg” in index.html
    and
    “../img/cupcake.jpg” in /FAQ/calories.html
    you can use “/img/cupcake.jpg” in both.

    That first slash does the magic. Root-relative is great for templates and reusable, modular designs where the html fragment might be used in documents with unknown directory depth. Plus you don’t have to fiddle with the dots if you decide to reorganize the document locations.

    Thanks,
    Chris

Leave a Reply

You must be logged in to post a comment.

You might also like other posts...

Learning to code can be fun!

Get started today with a free trial and discover why thousands of students are choosing Treehouse to learn about web development, design, and business.

Learn more