On this page · 10 sections
- Security Advisories Published on November 12
- Two release lists that overlap but do not match
- Key changes at a glance
- Retiring the legacy gateway reply prefix
- JetStream placement waits for the metalayer
- Permission refreshes and subscription correctness
- Recovery, restore and filestore fixes
- Remote proxies, leafnodes and MQTT
- Upgrade checklist
- Sources
TL;DR
NATS Server v2.15.1 and v2.14.8 remove support for the legacy $GR. gateway reply prefix and change JetStream placement, permission refresh and recovery behavior. Advisories published on November 12 show that they also fixed nine security flaws, and that 2.15.3 and 2.14.10, released on November 11, close eleven more across them and 2.15.2 and 2.14.9, including a critical MQTT OCSP bypass and several authorization callout and leafnode permission bypasses. Operators should go straight to 2.15.3 or 2.14.10.
Security Advisories Published on November 12 #
On November 12, NATS published security advisories for its recent releases, and nine of them cover fixes that shipped in 2.15.1 and 2.14.8, the versions this page is about. Later releases closed eleven more: 2.15.2 and 2.14.9 on October 26, and 2.15.3 and 2.14.10 on November 11. The CVSS 3.1 scores come from the advisories, and none lists a CVE.
| Advisory | Severity, CVSS | What it allowed | Fixed in |
|---|---|---|---|
| GHSA-vqv6-8g5v-c9c4 | High, 8.1 | Client-supplied identity fields bypass authorization callouts | 2.15.1 and 2.14.8 |
| GHSA-2wxw-wgx7-4ffx | High, 8.1 | Scoped signing key templates bypass required proxy authentication | 2.15.1 and 2.14.8 |
| GHSA-c5hj-fqj4-pj32 | High, 7.5 | MQTT packet buffering exhausts memory and CPU | 2.15.1 and 2.14.8 |
| GHSA-8fcg-2fq8-c8qc | High, 7.5 | Oversized MQTT subscription packets exhaust server resources | 2.15.1 and 2.14.8 |
| GHSA-72gq-694q-fj66 | High, 7.5 | Connected MQTT clients bypass packet buffering limits | 2.15.1 and 2.14.8 |
| GHSA-mf72-w5mg-h2mg | Medium, 6.8 | Removing TLS certificate pins does not revoke existing connections | 2.15.1 and 2.14.8 |
| GHSA-42wr-c22f-4h5c | Medium, 5.9 | HTTPS leafnode proxies receive credentials without TLS | 2.15.1 and 2.14.8 |
| GHSA-p8x9-xrv7-3g8j | Medium, 6.5 | JetStream restore format detection buffers excessive data | 2.15.1 only |
| GHSA-hm5m-vqj5-vf2q | Medium, 6.5 | Unexpected MQTT acknowledgements consume JetStream storage | 2.15.1; no 2.14.x fix through 2.14.10 |
| GHSA-8xmc-886f-g496 | Critical, 9.1 | MQTT listener OCSP peer verification silently omitted | 2.15.2 and 2.14.9 |
| GHSA-gc58-jp35-x246 | High, 8.1 | Leafnode permissions bypassed for internal MQTT subjects | 2.15.2 and 2.14.9 |
| GHSA-724w-jvcm-4c58 | High, 8.1 | Authorization callouts did not enforce allowed connection types | 2.15.2 and 2.14.9 |
| GHSA-65q4-982r-rm5c | High, 7.4 | OCSP responses not bound to the certificate being checked | 2.15.2 and 2.14.9 |
| GHSA-5v9x-4f9q-q7qj | High, 7.5 | Remote queue subscription weights exhaust server memory | 2.15.2 and 2.14.9 |
| GHSA-p29q-ccgc-hcg7 | High, 8.1 | Authorization callouts did not enforce JWT source restrictions | 2.15.3 and 2.14.10 |
| GHSA-7mrx-vpq7-fhmp | High, 8.1 | Ordinary users in an authorization account receive callout requests | 2.15.3 and 2.14.10 |
| GHSA-fwrx-9r9q-h7p4 | High, 8.1 | Leafnode peers bypass publish permissions for JetStream acknowledgements | 2.15.3 and 2.14.10 |
| GHSA-r9gv-x84w-62mr | High, 8.1 | Leafnode peers forge JetStream acknowledgements outside their permissions | 2.15.3 and 2.14.10 |
| GHSA-4fpp-8grw-j976 | High, 7.5 | Route pool index panic | 2.15.3 and 2.14.10 |
| GHSA-rr37-7hx9-8xw5 | Medium, 6.5 | Memory-backed stream purges cause excessive CPU use | 2.15.3 and 2.14.10 |
The most serious affect deployments that use authorization callouts, leafnodes with restricted permissions, and MQTT. GHSA-8xmc-886f-g496, the only critical one, means a deployment that enabled OCSP peer verification for the MQTT listener accepted client certificates without the revocation check before 2.15.2 and 2.14.9. GHSA-hm5m-vqj5-vf2q has no fixed 2.14.x release through 2.14.10, so MQTT deployments that need that fix must run 2.15.
Two release lists that overlap but do not match #
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 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.
Below, each item carries the version whose notes list it; items in both lists are marked as shared.
Key changes at a glance #
| Change | Who is affected | Action |
|---|---|---|
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 subjects | Inventory 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 limits | Check that existing assets fit the configured max_ha_assets before upgrading |
| 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 consumers | None; placement waits for caught-up peers |
| 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 counts | Map 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 rules | Test 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 movement | Review the timing assumptions in rebalancing runbooks |
| v2.15.1 only: leafnode isolation checked before subscription permission checks (#8727) | Hubs with large numbers of isolated leafnodes | None; the order of checks changes |
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 list this check.
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.
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).
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.
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 #
- Target 2.15.3 or 2.14.10 rather than 2.15.1 or 2.14.8, so the upgrade also closes the advisories fixed in October and November; MQTT deployments affected by GHSA-hm5m-vqj5-vf2q need 2.15.
- Read the 2.15 Upgrade Guide or the 2.14 Upgrade Guide that the release notes reference, depending on the target line.
- 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. - Record your current
max_ha_assetssettings if you are moving to v2.15.1, since that release enforces them consistently during placement, scaling and moves. - 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.
- Check any runbook that assumes consumers move immediately during rebalancing, because v2.15.1 waits until the new stream peers hold the data.
- Re-verify account JWT updates that change subject mappings. Invalid mappings are now rejected, and failed replacements keep the previous mapping.
- Validate remote proxy blocks, including https:// proxy URLs and the new rule that rejects proxy options when no proxy URL is specified.
- Where authorization callouts are in use, review which users the callout service exempts and which networks and connection types callout-issued JWTs allow, since five advisories concern callouts.
The Sentinel’s Call
Every NATS Server deployment should move to 2.15.3 or 2.14.10 rather than stop at 2.15.1 or 2.14.8, because the releases since closed eleven more advisories, one of them critical. Deployments that use authorization callouts, restricted leafnodes or MQTT are the most exposed. MQTT deployments affected by GHSA-hm5m-vqj5-vf2q need the 2.15 line, since no 2.14 release fixes it.
Our judgement, drawn only from the facts and sources above.
Sources
- Release Release v2.15.1 · nats-io/nats-server · GitHub github.com · Oct 9, 2026
- Release Release v2.14.8 · nats-io/nats-server · GitHub github.com · Oct 9, 2026
- nats-io/nats-server v2.15.3: Release v2.15.3 github.com · Nov 11, 2026
- nats-io/nats-server v2.15.2: Release v2.15.2 github.com · Oct 26, 2026
- nats-io/nats-server v2.14.10: Release v2.14.10 github.com · Nov 11, 2026
- nats-io/nats-server v2.14.9: Release v2.14.9 github.com · Oct 26, 2026
- Upgrade to NATS 2.15 | NATS Documentation docs.nats.io · Reference
- GHSA-vqv6-8g5v-c9c4: Client-supplied identity fields can bypass authorization callouts github.com · Nov 12, 2026
- GHSA-rr37-7hx9-8xw5: Memory-backed stream purges can cause excessive CPU use github.com · Nov 12, 2026
- GHSA-r9gv-x84w-62mr: Leafnode peers can forge JetStream acknowledgements outside their permissions github.com · Nov 12, 2026
- GHSA-p8x9-xrv7-3g8j: JetStream restore format detection can buffer excessive data github.com · Nov 12, 2026
- GHSA-p29q-ccgc-hcg7: Authorization callouts did not enforce JWT source restrictions github.com · Nov 12, 2026
- GHSA-mf72-w5mg-h2mg: Removing TLS certificate pins does not revoke existing client connections github.com · Nov 12, 2026
- GHSA-hm5m-vqj5-vf2q: Unexpected MQTT acknowledgements can consume JetStream storage github.com · Nov 12, 2026
- GHSA-gc58-jp35-x246: Leafnode permissions can be bypassed for internal MQTT subjects github.com · Nov 12, 2026
- GHSA-fwrx-9r9q-h7p4: Leafnode peers can bypass publish permissions for JetStream acknowledgements github.com · Nov 12, 2026
- GHSA-c5hj-fqj4-pj32: MQTT packet buffering can cause memory and CPU exhaustion github.com · Nov 12, 2026
- GHSA-8xmc-886f-g496: MQTT listener OCSP peer verification can be silently omitted github.com · Nov 12, 2026
- GHSA-8fcg-2fq8-c8qc: Oversized MQTT subscription packets can exhaust server resources github.com · Nov 12, 2026
Edited and approved by Jarosław Krzemiński. Spotted a mistake? Report a correction or read the corrections policy.




Comments