v2.12.14
cloudflare/artifact-fsv2.12.14Jul 30, 2026by github-actions[bot]
AI Summary
A maintenance release for NATS Server 2.12.x containing similar improvements and fixes as v2.14.4.
Key Highlights
- Updated Go version to 1.25.12
- Fixed authentication bypass with TLS verify_and_map
- Improved Raft election handling and peer removal
- Increased disk concurrency semaphore to 4096 slots
New Features
- Updated Go version to 1.25.12
- Fixed authentication bypass with TLS verify_and_map
- Fixed JWT validation crashes with whitespace-only permissions
- Fixed race condition between concurrent message removals
- Increased disk concurrency semaphore to 4096 slots
- Fixed MQTT packet identifier reuse
Full Release Notes
## Changelog ### Go Version - 1.25.12 (#8435) ### Dependencies - github.com/klauspost/compress v1.19.0 (#8385) - golang.org/x/crypto v0.54.0 (#8385) - golang.org/x/sys v0.47.0 (#8385) - github.com/antithesishq/antithesis-sdk-go v0.7.2-default-no-op (#8385) ### Improved JetStream - The Raft transport layer has been decoupled, improves testing but does not change server behaviour (#8181) - The disk concurrency semaphore has been increased to 4096 slots, up from the previous CPU-scaled count (#8336) - The disk concurrency semaphore can now be configured with the `max_concurrent_io` option in the `jetstream` config block (#8336) - Filestore underlying block cache buffers are now recycled to the pool when the weak reference is collected by the GC, which should smooth out memory usage with some usage patterns (#8395) - Inserts, iterations and deletes in AVL sequence sets are now faster in many cases, which speeds up the tracking of interior deletes (#8406) - Stream snapshots now attempt to determine the correct encode buffer size up front, avoiding many unnecessary allocations on streams with large numbers of interior deletes (#8405) - Reduced memory usage of the structure that is used to track subjects within a stream (#8412) ### Fixed General - `allow_non_tls` will no longer log an incorrect message at startup claiming that TLS is required (#8420) - Combining `no_auth_user` with auth callouts will no longer skip authentication checks when no `CONNECT` message is sent - JWT validation no longer crashes the server with whitespace-only permissions - Several paths that enforce the permissions of queue subscriptions no longer treat the whole permission as a subject literal - Several JetStream and MQTT endpoints now correctly guard against null values in JSON - Fixed an authentication bypass with TLS `verify_and_map` authenticating users with blank passwords Monitoring - The `healthz` endpoint will now skip and no longer report on expired JWT accounts (#8379, thanks to @ByapakSigdel) - The `varz` endpoint will now correctly report JetStream limits after they were changed via a config reload (#8394) JetStream - Malformed cluster replicated acks or delivered updates are now correctly rejected by the decoder (#8284, thanks to @uwezkhan) - Malformed cluster replicated skip or reset updates are now correctly rejected by the decoder (#8345, thanks to @uwezkhan) - Empty cluster replicated entries are now correctly ignored (#8347, thanks to @uwezkhan) - Decoded AVL sequence set node counts are now validated correctly on 32-bit systems (#8355, thanks to @uwezkhan) - Oversized cluster replicated messages are now validated correctly on 32-bit systems (#8357, thanks to @uwezkhan) - Raft elections now correctly ignore votes from removed peers (#8353) - Filestore encryption key files are now synced to disk more aggressively (#8366) - Raft now handles the append entry iterator returning no more entries correctly (#8372) - Fixed a bug in the filestore which could prevent some filestore block cache references from being weakened correctly, which could result in unexpected memory usage and GC pressure (#8380) - Attempting to update the consumer storage type now correctly returns an error (#8382) - Stream publish checks will now correctly reject messages that exceed the maximum store size before proposal (#8389) - Creating a clustered consumer immediately after creating a clustered stream should no longer respond with a `stream not found` error (#8410) - Replicated streams that were recreated while a node was down are no longer treated as an update by a returning node processing a snapshot, avoiding stale Raft groups from continuing to run and unexpected behaviour with consumers (#8413) - Stream snapshot endpoints now more strictly check the reply subject for validity MQTT - Packet identifiers for QoS1 and QoS2 are now issued by a monotonic counter, avoiding accidental ID reuse (#8358, thanks to @nberlee) - Pending QoS1 and QoS2 deliveries should no longer leak when the subscription is downgraded to QoS0 (#8359, thanks to @nberlee) - QoS2 messages released on a resumed sessions should no longer lose their QoS or packet ID (#8414) ### Complete Changes https://github.com/nats-io/nats-server/compare/v2.12.12...v2.12.14