2025-12-283 min readtroubleshootingauditcaching

Favicon serving checklist: status codes, MIME types, and cache headers

If your favicon works on your machine but breaks for users, the problem is often your server. Use this checklist to fix redirects, wrong Content-Type, and aggressive caching.

Favicon serving checklist: status codes, MIME types, and cache headers

Favicons are small files, but they are easy to serve wrong.

If you want an objective view of what your site serves, start here:

This post is a server-focused checklist for issues that cause "favicon works locally, fails in production".

Checklist: what a healthy favicon response looks like

For every icon URL your page references, you want:

  • Status: 200
  • No redirect chain
  • A sane Content-Type
  • Cache headers you understand (and can bust when you update)

If one icon URL fails, browsers can silently fall back to a cached icon or to /favicon.ico.

1) Status codes: avoid 404s, 403s, and surprise redirects

Serve the file at the exact URL in your <head>

If your HTML links to:

<link rel="icon" sizes="32x32" href="/favicons/favicon-32.png" />

Then /favicons/favicon-32.png must return 200.

If it returns 404, many browsers will not warn you. They will show an old cached icon and you will waste time debugging the wrong thing.

Avoid redirect chains for favicon URLs

A single redirect can work, but it is fragile and can create caching weirdness:

  • /favicon.ico -> /favicons/favicon.ico -> CDN rewrite -> origin

If you can, serve the icon directly at the URL you link to.

The Favicon Checker will show you redirects and non-200 responses.

2) Content-Type: do not serve icons as text/html

If your server rewrites unknown paths to your app shell, your favicon URL can return HTML.

That looks like a successful 200, but it is still broken.

Here is what you want most of the time:

  • favicon.ico: Content-Type: image/x-icon (or image/vnd.microsoft.icon)
  • PNG favicon files: Content-Type: image/png
  • site.webmanifest: Content-Type: application/manifest+json (or application/json)
  • browserconfig.xml: Content-Type: application/xml (or text/xml)

If you see text/html on an icon URL, fix your static asset routing.

3) Cache-Control: your favicon should be cacheable, but updatable

Favicons are requested a lot. You want caching.

But you also need a plan for updates.

A safe default for immutable versioned URLs

If you version your URLs (file name changes on updates), you can cache for a long time.

Example:

  • /favicons/favicon-2025-12-28.ico

That can safely be cached aggressively because the URL changes when the content changes.

A safe default for stable URLs

If your URLs stay stable (like /favicon.ico), caches can keep the old file for longer than you expect.

When you update, the fastest fix is usually changing the URL:

  • For PNG links, add a query string:
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32.png?v=2025-12-28" />
  • For ICO, renaming is often more reliable than a query string:
<link rel="icon" type="image/x-icon" href="/favicons/favicon-2025-12-28.ico" />

If you need a full end-to-end checklist, see Favicon not updating? Fix it with a cache-busting checklist.

4) CDN and edge caching: update the right layer

If you deploy behind a CDN, you can have three different caches:

  • The browser cache
  • The CDN cache
  • Your origin server cache settings

If you replace favicon.ico at the same URL, you may need to purge the CDN cache for favicon paths, or use URL-based cache busting so you do not depend on purges.

5) Verify the whole setup in one pass

After you make server changes:

  • Run the Favicon Checker again.
  • Confirm your HTML tags are detected.
  • Confirm every icon URL returns 200.
  • Confirm sizes match what the tags claim.

If the checker is clean and you still see the old icon in your daily browser, the issue is almost always local caching. Use a clean profile or a different device.

Optional reading (authoritative references)

Related tools

Share

Send this post to a teammate or keep it for later.