On this page · 9 sections
  1. Two release lists that overlap but do not match
  2. Key changes at a glance
  3. Retiring the legacy gateway reply prefix
  4. JetStream placement waits for the metalayer
  5. Permission refreshes and subscription correctness
  6. Recovery, restore and filestore fixes
  7. Remote proxies, leafnodes and MQTT
  8. Upgrade checklist
  9. Sources

TL;DR

NATS Server v2.15.1 and v2.14.8 both remove support for the legacy $GR. gateway reply prefix and reserve it on client ingress. Both also change JetStream placement, permission refresh and recovery behavior. Operators of clustered, gateway and leafnode deployments should review these notes before upgrading.

Two release lists that overlap but do not match #

Clustered NATS deployments often upgrade without reading the full list of changes, and that is where surprises come from. The NATS Server v2.15.1 release notes and the NATS Server v2.14.8 release notes share many entries, but neither list is a subset of the other. Treat each page as the authority for its own version.

Both pages carry a published date of 2026-10-09 in the source metadata, and both were retrieved on 2026-10-16. Both list the same dependency updates, github.com/klauspost/compress v1.20.1 and github.com/nats-io/nats.go v1.53.1, and both reference pull request #8737 for them. The Go toolchain is the one difference in that section: v2.15.1 names Go 1.27.2 and v2.14.8 names Go 1.26.9, with both referencing #8740.

The two releases also point to different upgrade guides. The v2.15.1 notes refer readers to the 2.15 Upgrade Guide for backwards compatibility with 2.14.x. The v2.14.8 notes refer to the 2.14 Upgrade Guide for compatibility with 2.12.x, and they state that the 2.13.x version was skipped. Read the guide that matches the version you plan to run.

This article labels each item with the version whose notes list it. Where a change appears in both lists, it is marked as shared. Where a change appears in only one list, the other version's notes do not mention it, and the sources do not say whether it was carried over.

Key changes at a glance #

ChangeWho is affectedAction
Shared in v2.15.1 and v2.14.8: support for the legacy $GR. reply prefix removed, and the prefix reserved on client ingress (#8615)Gateway operators, and any client or server that publishes to gateway reply subjectsInventory every component that might still emit the prefix before upgrading
v2.15.1 only: max_ha_assets enforced consistently by the metalayer leader during stream and consumer placement, scaling and moves (#8639)Clustered JetStream operators who set HA asset limitsRecord current limits and test placement and scaling in staging
Shared in v2.15.1 and v2.14.8: placement prefers peers that have caught up with the metalayer (#8643)Clustered JetStream users who create, scale or delete streams and consumersWatch API response times during scaling events
v2.14.8 only: stream scale-down requests rejected when the target replica count has no configured account tier (#8608)Operators whose scripts reduce stream replica countsMap every target replica count to a configured tier and handle rejections explicitly
Shared in v2.15.1 and v2.14.8: subscription deny filters rebuilt atomically when inherited account permissions refresh (#8622)Operators who rely on inherited account permissions and deny rulesTest permission refresh paths after upgrading
v2.15.1 only: consumers no longer moved to new stream peers before those peers hold the stream data (#8678)Operators whose rebalancing runbooks assume immediate consumer movementReview the timing assumptions in rebalancing runbooks
v2.15.1 only: leafnode isolation checked before subscription permission checks (#8727)Hubs with large numbers of isolated leafnodesMeasure hub CPU before and after the upgrade

Retiring the legacy gateway reply prefix #

The most consequential compatibility change in both lists is the removal of support for the legacy $GR. reply prefix. The v2.15.1 notes say this prefix was used by servers prior to v2.1.2, and that support for sending and handling it has been removed (#8615). The same pull request reserves the prefix on client ingress, which stops clients from publishing to gateway reply subjects that use it. The NATS Server v2.14.8 release notes record the same removal and the same reservation under their Gateways entries.

For a fleet where every server is recent, the reservation mainly acts as a hardening measure. For gateway topologies that still include very old servers, it becomes a compatibility question. Neither set of notes describes a migration path or explains how a mixed-version gateway behaves with the prefix. Your own inventory has to answer that question. Check gateway configurations, client libraries and custom tooling that publishes to reply subjects. Do not assume a mixed fleet will keep working, because the sources do not say that it will.

JetStream placement waits for the metalayer #

Both releases make stream and consumer placement more careful about cluster state. The notes say that placement now prefers peers that have caught up with the metalayer (#8643), which reduces delays in API responses. The same pull request also covers requests that arrive during metalayer catchup. Stream and consumer create and delete requests in that window now receive responses once catchup completes. R1 consumer create requests keep their responses even when the consumer is deleted immediately afterwards. Both sets of notes list these fixes under #8643.

The v2.15.1 notes add two placement changes that the v2.14.8 notes do not list. The first is the consistent enforcement of max_ha_assets by the metalayer leader during placement, scaling and moves (#8639). The second is that consumers are no longer moved to new stream peers until those peers hold the stream data (#8678). If your automation scales streams and consumers in quick succession, either change can alter timing. An operator who assumed consumers moved immediately should revisit that assumption and confirm the new order in a test cluster.

The v2.14.8 notes include a different placement guardrail. Stream scale-down requests are rejected when the target replica count has no configured account tier (#8608). Scripts that reduce replica counts to values outside the configured tiers will now receive rejections. Those scripts should parse and report the errors rather than retry them in a loop. The v2.15.1 notes do not repeat this entry, so this article does not claim the check exists in the 2.15 line.

Permission refreshes and subscription correctness #

A group of fixes in both lists concerns what happens when account state changes while clients are connected. Both releases say that outstanding reply permissions are preserved when inherited account permissions are refreshed without changing the response policy (#8620). Both also say that subscription deny filters are rebuilt atomically during the same refresh (#8622). The notes state that this closes a window in which denied messages could be delivered. For environments that depend on deny rules, that is a correction worth testing directly.

Both lists also say that cached subscription results are cleared when an already connected client sends another CONNECT (#8641). This prevents stale results from being reused after an account change. Queue subscription deny permissions are now checked against the mapped delivery subject (#8616). Both releases further state that account JWT updates now reject invalid subject mappings instead of reporting success, and that failed replacements no longer remove existing mappings (#8627). That last behavior deserves a test. An operator who believed a failed update had succeeded may find that the previous mapping is still in effect.

The v2.15.1 notes add two leafnode-related items. Leafnode publish permissions are now checked against the transformed subject sent over the leafnode connection (#8530), which removes the need to also allow the original stream import subject. Leafnode isolation is checked before subscription permission checks (#8727), which reduces CPU on hubs with many isolated leafnodes. The v2.14.8 notes list the transformed-subject change under #8530 but not the isolation ordering change.

Recovery, restore and filestore fixes #

Several recovery fixes appear in both lists. Stream restore waits for the preferred node to become leader, which avoids an incorrect create response during clustered restore (#8690). The consumer created time is preserved after recovery (#8621). Filestore compaction respects the configured sync settings when it replaces a message block (#8629). A race during filestore compaction that could cause consumers to skip messages or lose redelivery tracking is fixed in both releases (#8623). Operators running clustered JetStream should read these entries together, because they all concern data correctness during restart and restore.

Some recovery items appear only in the v2.15.1 notes. Interest cleanup no longer compacts a stream past its last sequence during recovery (#8710). Raft nodes no longer leak their WAL if stopped before route connections are available (#8711). Failed clustered stream restores clean up without deleting a subsequently recreated stream or losing a stream rm response (#8702). The v2.15.1 notes also list fixes for membership change, learner scale-up and metalayer commit recovery (#8672), and for migration and R1 scale-up issues that could delete a running store (#8673). The v2.14.8 notes do not list these entries, so this article does not claim the older line includes them.

The v2.15.1 notes also say that stream restore format detection now stops after the first S2 chunk (#8693). The source states only what detection does, so confirm the effect against your own restore tooling and archives rather than assuming it applies to every backup you hold.

Remote proxies, leafnodes and MQTT #

Both lists include remote proxy changes. The notes say remote proxies now support TLS with https:// proxy URLs and an optional proxy tls block (#8701). They also say remote proxies no longer warn incorrectly that nats:// URLs are unsupported, and no longer lose the hub's initial INFO message. Remote proxy options are now rejected when no proxy URL is specified (#8701). Validate remote proxy blocks in staging before rolling them out, because this new rejection rule changes how such blocks load.

On the MQTT side, the v2.15.1 notes say QoS2 PUBLISH and PUBREL processing is now pipelined for increased throughput (#8416). They also report reduced allocations and buffer copying for QoS1 and QoS2 handling (#8624, #8625), and they add that packet lengths are validated earlier against max_payload while non-QoS 2 PUBREC packets are handled correctly (#8692). The v2.14.8 notes include the partial-packet change and the max_payload validation, but they do not list the pipelining or PUBREC changes. The sources contain no benchmark figures, so measure MQTT throughput on your own workload before you count on a gain.

Leafnode operators should also note the WebSocket details. Leafz now reports whether a leafnode connection uses WebSockets (#8683), and both releases make TLS state available to auth callouts when leafnodes connect over WebSockets (#8686). Leafnode clients are shed alongside regular clients during lame duck shutdown, which avoids a thundering herd (#8695). Closed leafnode connections are removed from the account's leafnode list, which reduces retained memory (#8637).

Upgrade checklist #

  1. Open the 2.15 Upgrade Guide referenced by the v2.15.1 notes, or the 2.14 Upgrade Guide referenced by the v2.14.8 notes, depending on your target. The sources do not give URLs for these guides, so locate them from the release pages before you plan.
  2. Inventory every gateway, client and tool that might emit the legacy $GR. reply prefix. Both versions remove support for it and reserve it on client ingress.
  3. Record your current max_ha_assets settings if you are moving to v2.15.1, since that release enforces them consistently during placement, scaling and moves.
  4. Review scripts that reduce stream replicas. If you are on v2.14.8, confirm that every target count maps to a configured account tier, because that release rejects scale-downs that do not.
  5. Check any runbook that assumes consumers move immediately during rebalancing, because v2.15.1 waits until the new stream peers hold the data.
  6. Test inherited account permission refreshes and deny rules in staging, since both lists describe atomic rebuilds of subscription deny filters.
  7. Re-verify account JWT updates that change subject mappings. Invalid mappings are now rejected, and failed replacements keep the previous mapping.
  8. Validate remote proxy blocks, including https:// proxy URLs and the new rule that rejects proxy options when no proxy URL is specified.
  9. Upgrade a non-production cluster first, then run stream and consumer create, scale and delete operations while you watch API response times.
  10. Roll out to production one cluster at a time, and keep rollback steps ready for any gateway or leafnode behavior you cannot verify in staging.

The most reliable way to read these notes is version by version. The v2.15.1 list contains the placement, restore and recovery work specific to that release. The v2.14.8 list contains the tier guardrail on scale-down and several entries that the newer list does not repeat. Confirm your target version against its own release page before you schedule the change window.

Sources

  1. Release Release v2.15.1 · nats-io/nats-server · GitHub github.com · Oct 9, 2026
  2. Release Release v2.14.8 · nats-io/nats-server · GitHub github.com · Oct 9, 2026

Next reading

Edited and approved by Jarosław Krzemiński. Spotted a mistake? Report a correction or read the corrections policy.