Forcing Firefox to refresh a favicon from its cache

28 Sep 2018


For quite some time now, I’ve noticed that Firefox gets the favicon for certain sites mixed up. This has been an issue that persisted pre- and post-Quantum. Here’s an example of what I’m talking about:

Unless the acquisition of the century has occurred, the favicon for recreation.stanford.edu should definitely not be Facebook’s logo. While this issue isn’t devastating, it is irksome. In particular, I often scan the list of suggestions based largely on the favicon instead of reading the URLs.

The issue is not solved by deleting the page from history or forcing a refresh of the favicon from the browser. Instead, the problem has a deeper cause.

Firefox’s favicon cache

Firefox keeps all of its favicons in a cache. Whenever a page is displayed in the history (or on a tab), the favicon is fetched from this cache. Similarly, newly discovered favicons are kept here. Firefox keeps all of its stored information (including this cache) in a profile directory. On a typical Linux machine, this ~/.mozilla/firefox/abcd1234.default/, or the like. See here for more information on how to locate your profile.

Within this profile directory, there is the conveniently-named favicons.sqlite database. There are 3 SQLite tables in this database:

Table Function
moz_pages_w_icons Lists webpage URLs that have a favicon
moz_icons Lists favicons, including the location and the actual icon
moz_icons_to_pages Maps page IDs to icon IDs, bridging the two previous tables

When Firefox gets a favicon wrong, it’s because this cache is holding the incorrect one. To fix this, you can delete the page and its associated icon directly from this table.

Manually cleaning up the favicon cache

If you know some SQL, then you probably already know what to do from here:

  1. Find the page ID belonging to the faulty page URL from moz_pages_w_icons, and delete its entry
  2. Find the icon ID for this page from moz_icons_to_pages, and delete its entry
  3. Find the icon for this icon ID from moz_icons, and delete its entry

This will cleanly delete the improper association(s) from the table, so a the correct one can be made anew. No need to restart Firefox, either! Seasoned SQL users can likely perform these tasks with a few nested statements.

Otherwise, you can download this nifty delfavicon Python script, which has a much nicer user interface. Simply specify a domain or URL substring from commandline. The script will also show you which pages it plans to delete, and ask for confirmation.

For those who are interested, here’s the basic code that will accomplish the task:

import sqlite3

# REPLACE THIS WITH THE PATH TO YOUR OWN favicons.sqlite
favicon_db_path = "/home/me/.mozilla/firefox/abcd1234.default/favicons.sqlite"

# REPLACE THIS WITH WHAT YOU WANT TO REFRESH
domain_to_del = "recreation.stanford.edu"

conn = sqlite3.connect(favicon_db_path)
c = conn.cursor()

comm = "SELECT id, page_url from moz_pages_w_icons WHERE page_url LIKE '%{}%'".format(domain_to_del)
moz_pages_w_icons_rows = [row for row in c.execute(comm)]
page_urls = sorted(list(set(row[1] for row in moz_pages_w_icons_rows)))

page_ids = list(set(row[0] for row in moz_pages_w_icons_rows))
icon_ids = set()
for page_id in page_ids:
    comm = "SELECT icon_id FROM moz_icons_to_pages WHERE page_id == {}".format(page_id)
    icon_ids.update([row[0] for row in c.execute(comm)])
icon_ids = list(icon_ids)

for page_id in page_ids:
    comm = "DELETE FROM moz_pages_w_icons WHERE id == {}".format(page_id)
    c.execute(comm)
for icon_id in icon_ids:
    comm = "DELETE FROM moz_icons WHERE id == {}".format(icon_id)
    c.execute(comm)
    comm = "DELETE FROM moz_icons_to_pages WHERE icon_id == {}".format(icon_id)
    c.execute(comm)

conn.commit()
conn.close()

Tags: config