Jumping from 2026.1 ESR to 2026.7 - What I found

Two corrections from @Moin, on the Reactions opt-out and on how Upcoming Changes actually behave on ESR. Both worth reading in full.


First off, congrats to the Discourse team on the new ESR, and thank you for the work that went into it. Six months of releases landing in one supported checkpoint is a LOT of engineering, and the fact that there’s now a proper release site and changelog to dig through made this research a lot easier than the previous 4 years.

I’m on 2026.1.5 ESR. I’ve gone release after release before trying to find a setup where upgrades go as smoothly as possible.

I dug through everything between 2026.1.5 and 2026.7.0 before touching anything, and I figured the notes would be useful to anyone else sitting on 2026.1 right now trying to decide: patch now, or jump now?

I patched to 2026.1.6 today for the security fixes, and I’ll move to 2026.7.0 in the first week of next month when I have time to properly test my theme components and other things.


The version: stable gotcha!

If, like mine, your app.yml says:

  version: stable

…then your next rebuild puts you on 2026.7.0, whether you meant to or not. stable is a backward-compatibility alias for esr, and esr always points to the latest ESR, which changed today.

There’s no downgrade path that I know of so if you rebuild just to grab the security fix, you get the whole six-month jump with it!

To stay on 2026.1 and get security patches only, pin explicitly:

  version: release/2026.1

To move to the new ESR and not get moved again automatically in six months:

  version: release/2026.7

2026.1 is supported until September 2026. 2026.7 runs to March 2027. So the jump is coming regardless, it’s only a question of whether it happens on your schedule.


Prerequisites

PostgreSQL 15 is now the minimum. Check yours from inside the container:

cat /shared/postgres_data/PG_VERSION

Mine came back 15, so I’m clear. If you’re on 13 or 14, I believe that’s a separate upgrade to do before the version jump.

Worth noting: the container image now ships PG 18 alongside 15 but I’m declining it for now one variable at a time.


Downtime?


Take a backup first, and lock the forums with maintenance mode.

No downtime, but they’re not instant on a mature forum:

Rebuild took < 5 minutes on my VPS, plan on ~ 10 minutes on most web hosts but also depends a lot on your forum’s post count so plan a window of 30 to 45 mins.


Security: what you’re exposed to on 2026.1.5

17 advisories apply if you’re on 2026.1.5. Everything published before 30 June was already fixed in your build. All 17 are patched in both 2026.1.6 and 2026.7.0, which is what makes patch-first a legitimate option.

  • 1 critical - cache poisoning / XSS via color scheme cookies
  • 2 high - RCE via malformed HEIF file; stored XSS via unescaped chat-transcript username in the rich text editor
  • 13 medium, 1 low - stored XSS in the review queue, staff action logs, post actions, and local-dates; hidden tag name and tag description leaks; restricted topic titles exposed via canonicalized URLs; shared-draft title/excerpt leaks; onebox domain blocklist bypass via case-sensitive comparison; AI bot conversation eavesdropping; PM content reachable through AI reviewables; chat onebox channel/thread ID mismatch; hidden first-post excerpt emitted in Q&A JSON-LD

If you’re patching only, release/2026.1 + rebuild closes all of them.


My pet peeve: Things that will change without you asking

This is the section I most wanted the last few years. On the jump to 2026.7, these are some of the behavior changes that arrive on their own:

  1. Discourse Reactions enabled by default for all sites. The rollout reached stable in early July 2026. If you don’t run Reactions today, it’s coming.

  2. Uncategorized is being removed. Settings related to Uncategorized are affected and will be removed entirely once the change goes permanent. Managed as an opt-out for now.

  3. The rich_editor site setting is gone. The rich editor is now unconditional. The per-user composition_mode preference is the only remaining way to choose between markdown and rich text. The Markdown preview toggle was also removed - the MD/RTE mode toggle replaces it.
    (Keep this only if it’s true in your specific environment; otherwise remove or qualify it.)

  4. Simpler email subject lines. Currently in beta. Heads up: enabling this does not overwrite your email_subject site setting; your customizations are preserved unless you manually clear them. If you want to use the new defaults, you’ll need to clear your custom email_subject and related site texts first.

  5. Horizon high-context topic cards reached stable in June. Only relevant if you’re on Horizon, and there’s a theme setting to revert to simple cards.

The good news: all of these now arrive through the Upcoming Changes system, meaning these changes are not present in 2026.1.5. You get a config page, advance notice, per-change opt-out, and a fix that specifically stops a rollout from clobbering a setting you’ve already customized yourself.

If, like me, you’ve been frustrated by settings moving around between releases, that system is the answer, and staying on 2026.1 keeps you on the build that predates it. First thing I’ll do after jumping is go through Upcoming Changes and set every pending item deliberately, before anything promotes itself.


If you run custom themes or components

This is where I expect to spend my testing time, and part of why I’m not jumping today:

  • Admin warnings now surface for pending deprecations. As of mid-July, any remaining .hbs usage triggers a warning banner for admins, and legacy code in your components will show admin notices generally. Better to know, but it’s a review pass. Check every theme you have installed, not just the active one, since notices only appear for themes and components actually in use.
  • .hbs is deprecated in themes and plugins. 2026.7 is the last ESR with .hbs support; Discourse plan to drop it during the 2026.8.0-latest cycle, so 2027.1 will be the first ESR without it. Migrate templates to the .gjs format. There’s a codemod that automates most of it, and the team have offered to run it and open a PR for people stuck on specific plugins.
  • .js.es6 is deprecated too, on the same timeline. This one’s trivial: rename the files to .js.
  • Legacy widget shims and old deprecation paths cleaned up. The widget rendering system itself was removed before 2026.1, so if you were still on createWidget and friends you found out months ago. What 2026.7 drops are the remaining shims and legacy paths for discourse.breadcrumbs.*, add-flag-property, add-header-panel, and bootbox.
  • Plugin outlet deprecations are more visible now. Renamed outlets warn instead of just disappearing.
  • Theme settings handling has changed, which can affect when settings are available at boot. Worth verifying if your component reads settings early.
  • Legacy mobile-mode site settings and the old mobile/desktop split are effectively gone, layouts are now purely width-responsive. If your CSS targets mobile and desktop separately, test on an actual phone after upgrading.
  • Under the hood: continued framework upgrades (Ember, ember-cli), the Rolldown migration completed, further jQuery removal, and improved TypeScript support for themes and plugins.

House Ads users: inline JS is now blocked in house ads, and the admin UI was rebuilt in FormKit. house_ads_after_nth_root also appears to be honored in the nested replies view now.


Notable new features

37 features were highlighted across these six months. The ones I think matter most for a general community forum:

  1. Upcoming Changes - the config page and rollout system described above.
  2. Nested replies - experimental threaded/tree-style topic view, configurable per topic and per category, with bulk enable from the topic list and a reworked mobile experience.
  3. One-time email code login and signup (enable_local_logins_via_code) - passwordless, currently alpha. Sign-up requires only an email plus a code.
  4. New admin category management page plus simplified category creation. A full directory of categories and their types.
  5. Bulk actions across the board - bulk tag management (add/remove/replace), bulk pin/unpin, and bulk suspend for unactivated users, alongside a new activation-status filter on Admin → Users. That last combination is excellent for cleaning up spam registration waves.

Also worth a mention: an explicit default homepage setting, pinned emoji groups with bulk custom emoji import/export, dots now allowed in tag names, a dedicated tag editing page, full app mode for embedding, group sync for both OAuth2 and OpenID Connect, and live PR status icons on inline GitHub oneboxes.


Why I patched first

Nothing above is a reason not to move to 2026.7. The Upcoming Changes system alone makes it worth doing, and I’m going in the first or second week of next month.

But the security fixes are available on both branches, which meant I could decouple the urgent part from the part that needs testing. Like the rich editor is now unconditional. I’m sure reading around the forums I’ll find a quick path, hopefully.

Patching today closed every advisory. The jump now gets a proper window where I can go through Upcoming Changes deliberately and check my theme components on desktop and mobile without racing a critical CVE.

If you’re on 2026.1 and short on time this week, I’d suggest the same. If you have the time, go straight to release/2026.7, just pin it explicitly, and check your Postgres version.

Thanks again to the team. The changelog site made this a much less painful investigation than it would have been a year ago.


Disclosure: I used AI in helping me to lay this post out; otherwise, I would not have the time to post this. Please point out anything I need to add, remove or change.

It’s enabled by default (not only for new forums but also for existing) but you can still use the discourse_reactions_enabled site setting and turn it off after updating. You can still opt out.

I am not sure this is going to work for two reasons. I think being on ESR will mean that you miss upcoming changes that move through all stages before the next ESR release happens. Simplified category setup is an example for that. While admins updating each month had the chance to try this and provide feedback, you just get the result like any other code change without an upcoming change.
Also, you can opt-in to changes more early or opt-out after it was enabled automatically when it’s promoted to beta - but you cannot prevent that it’s automatically enabled. (But I don’t think this is a problem in your case)

Of course, checking out changes in alpha to be aware of what’s coming makes sense. You can already test the feature as an admin without it affecting your users and you can quickly opt-out after you performed an update that enabled it - but since you are on ESR there won’t be an update that promotes the upcoming change. For you nothing will promote itself until your update to a later version, but this also means you miss the option to try before stuff is changed permanently or you can try how it’s today, but won’t be able to try the improvements happening in further iterations.

@Moin, genuinely appreciated! This is also why I sit on the ESR jump ~ a week. The feedback and corrections for things I have wrong etc. …beats anything that I can figure out on my own. Will update post. Thank you!

Another thing worth noting is that the previous ESR will continue to get security patches for the next two months.

You did say this here:

But this made me want to clarify/emphasize the point:

Patch first is a legitimate option not only right now, but also for a little while longer.

But stable also worked this way?

So I don’t think this is a behavioural change - they’ve just renamed it to esr and that also updates you to the latest version on that branch upon a new version being published at the point you rebuild. This is entirely expected.

As always, if you really want to be super careful, at the minimum bootstrap the new version using a dual container setup or even better maintain a staging server and checkout all the updates against your plugin population before committing it to Production.

If you don’t use a staging system imho it’s almost better to drip feed latest all the way along and deal with compatibility issues on a case by case basis as a drip feed as opposed to having a large amount of breaking changes dumped into Production at once.

Otherwise a very interesting and informative post, thanks!

Thanks. Also note discourse-health-check v1.0.4 is now updated:

Two fixes:

  1. Discourse replaced Unicorn with Pitchfork (default in 2026.2, Unicorn removed entirely
    in 2026.4), so the web server check now detects both. Thanks @RGJ for flagging this
    back in June.

  2. The service probes were matching their own command line. pgrep -f <name> so pgrep matched itself and the check passed whether or not the service was actually up. Sidekiq had been reporting “running” unconditionally since 1.0.0. It could have been dead and you’d still get a green check and exit code 0 from cron. Same root cause as the Puma false
    positive in 1.0.1, which turned out to have been renamed rather than fixed.

Oh, and now reports your PostgreSQL major version and flags anything below 15.


One more thing to carry through the upgrade, if you embed YouTube:

Discourse sends Referrer-Policy: same-origin by default, and YouTube rejects embed configuration requests that arrive without a referrer. You get Error 153 and videos won’t play. I hit this back in November and fixed it with a Cloudflare Transform Rule setting Referrer-Policy: strict-origin-when-cross-origin:

I checked the changelog while writing this post. There are no commits touching Referrer-Policy anywhere between 2026.1.5 and 2026.7.0, so this still isn’t fixed in core. If you have a workaround in place for it, don’t clean it up during the upgrade.

For anyone not on Cloudflare, a theme head entry does the same job:
<meta name="referrer" content="strict-origin-when-cross-origin">

Not able to edit that topic, it’s closed. So not it should be “set static” not add: