v2.14.4
greensock/GSAPv2.14.4Jul 30, 2026by github-actions[bot]
AI Summary
NATS server release focusing on JetStream performance improvements and bug fixes, including Raft transport layer decoupling and enhanced disk concurrency handling.
Key Highlights
- Raft transport layer decoupled for improved testing
- Disk concurrency semaphore increased to 4096 slots with configurable max_concurrent_io option
- Filestore block cache buffers recycled to pool via GC weak references
- Fixed authentication bypass with TLS verify_and_map
- MQTT packet identifiers now issued by monotonic counter
Full Release Notes
## Changelog Refer to the [2.14 Upgrade Guide](https://docs.nats.io/release-notes/whats_new/whats_new_214) for backwards compatibility notes with 2.12.x. Please note that the 2.13.x version was skipped. ### Go Version - 1.26.5 (#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) - Calculating and looking up sequences in delete maps for file-backed streams with large numbers of interior deletes is now faster and holds locks for less time (#8403) - 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) - Stale error responses on source or mirror creation are now dropped by recreating the subscription (#8356) - 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 blocks with unsynced or truncated key files are now removed and counted as lost data instead of failing to recover altogether (#8365) - 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 string ownership when handling the expected last sequence per subject in a batch (#8377) - Fixed a race condition between concurrent message removals via limits that could unexpectedly disable writes into a filestore (#8378) - 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) - Fixed a race condition between storing messages in the filestore and block compactions (#8400) - The filestore no longer skips sparse delete blocks when processing deletes from a snapshot (#8404) - The consumer reset endpoint responses are no longer dropped when sent through a service import (#8407) - Creating a clustered consumer immediately after creating a clustered stream should no longer respond with a `stream not found` error (#8410) - Raft proposals now require the term to be passed down from JetStream, preventing situations where stale proposals from a previous term could make changes in a new term after a fast election (#8370) - 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) - MQTT clients can no longer subscribe to `$MQTT.>` subjects, closing a potential permission bypass ### Complete Changes https://github.com/nats-io/nats-server/compare/v2.14.3...v2.14.4