v2.14.4

BuilderIO/gpt-crawlerv2.14.4Jul 30, 2026by github-actions[bot]

AI Summary

A maintenance release for the NATS server focusing on JetStream performance improvements and fixing critical bugs, including authentication bypasses and data corruption issues. Note that version 2.13.x was skipped.

Key Highlights

  • Decoupled Raft transport layer for JetStream
  • Improved performance of AVL sequence sets and snapshots
  • Fixed critical authentication bypass vulnerabilities
  • Fixed data corruption issues in filestore and Raft groups

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