Unread count shows Unread (14) but /unread is empty

On this fine Thursday morning, I bring an interesting conundrum before you. I’m seeing what looks like a false positive unread counter on my site.

What happens

The top nav shows Unread (14). But when I click it and go to /unread, there are no unread Topics listed. The page says there is nothing left unread.

Other non-staff users are seeing the same issue too, though with different unread counts.

In the Discourse app on iOS, I also see an unread count when there are no unread Topics, again sometimes with a different number.

  • Platform: desktop web and Discourse app on iOS
  • Affects: multiple users
  • Site: eurth.org

What I tested

I tested in Safe Mode:

  • https://eurth.org/?safe_mode=no_themes,no_plugins
  • https://eurth.org/unread?safe_mode=no_themes,no_plugins

The issue still happens there, so it does not appear to be caused by themes or client-side plugin customizations. There are no whispers in any topic, so it’s likely not that either.

I also cannot use Dismiss, because there is no Dismiss button on /unread when the unread list is empty.

Expected behaviour

If the nav says Unread (14), I should see 14 unread Topics on /unread, or at least some visible unread Topics.

Actual behaviour

  • nav says Unread (14)
  • /unread is empty
  • no Dismiss button is available
  • issue persists in Safe Mode

Questions

  • Is there a known way to rebuild/reset unread state for one user?
  • Is there a server-side inconsistency that can cause unread counts to persist even when /unread is empty?

Previously, I’ve asked the AI on ask.discourse.org about the issue, and in the end it advised that I post a bug report here.

1 Like

ah the phantom unreads has bitten your site!

have you changed any category permissions recently or moved some topics to a secure category? something has changed the tracking state.

wouldn’t you want to reset it for all users if others are having the same issue?

i think this can be fixed for everyone via rails console but it’s a bit tricky and i have to figure it out and test it first. i am on mobile at the moment but i’ll try to post a solution in a bit if no one else does.

2 Likes

Hello,

We are aware of this bug and trying to resolve it. We are all annoyed by it :wink:

3 Likes

Yes. In private our staff worked on a category similar to Documentation, which was recently made public once it was finished.

Yes, yes indeed. My idea was to test it on myself first, and then fix for everyone. Since it’s such a complicated bug to test (at least for me), I didn’t want to get everyone’s hopes up until there’s a working solution.

Thank you for the confidence. This morning I noticed the May 2026 monthly release v2026.05, and thought it might fix the issue, but it still persists. I’m sure the Team is on it. Discourse is awesome.

Oh, gosh. :flushed_face: Admitedly I’ve gone through read all the realted bug reports. For a hot minute, I even considered just hiding the “Unread” tab from the navigation, and just ignoring it. But that’s not going to solve anything, is it. Looks like it’s even following me around here on Meta.

1 Like

ok, this rails script will act as a global “mark all as read” and force the unread count back to 0 for all users, so unfortunately it will clear any legitimate unread counts in addition to any phantom unreads. we can do this with a sql command in rails. but note that it doesn’t fix the root bug. also, good idea if you have a recent backup handy, but i tested this on my dev forum and it worked.

cd /var/discourse
./launcher enter app
rails c

paste the whole folowing block and hit enter

sql = <<~SQL
  UPDATE topic_users
  SET last_read_post_number = topics.highest_post_number
  FROM topics
  WHERE topics.id = topic_users.topic_id
    AND COALESCE(topic_users.last_read_post_number, 0) < topics.highest_post_number
    AND topic_users.notification_level IN (2, 3, 4) -- Tracking, Watching, Watching First Post
SQL

# run the update
result = ActiveRecord::Base.connection.execute(sql)
puts "Successfully cleared #{result.cmd_tuples} unread topics site-wide."

# force client browsers to drop their cached state and sync with the database
MessageBus.publish("/topic-tracking-state", { clear: true })

users may have to hard refresh to see the cleared unread state.