v2.12.1

nats-io/nats-serverv2.12.1Oct 14, 2025by github-actions[bot]

AI Summary

This is a patch release (v2.12.1) of the NATS server that focuses on bug fixes and performance improvements, particularly in JetStream and filestore functionality. The release updates Go to 1.25.3 and includes new features like WebSocket leafnode proxy support, a new embedded server API function, and write deadline configuration options.

Key Highlights

  • Go version updated to 1.25.3
  • Major JetStream filestore performance improvements including cache optimizations, binary search for sequence lookups, and efficient memory allocation
  • Fixed critical filestore bugs including tombstone loss with secure erase and incorrect cache expiration
  • Added WebSocket leafnode HTTP proxy support and write_deadline configuration options
  • Improved monitoring with jsz endpoint now reporting leader counts

New Features

  • NewServerFromConfig function for parsing external configuration files in embedded server API
  • WebSocket leafnode connections can now use HTTP proxy via proxy settings in leafnode remotes
  • write_deadline option added to cluster, leafnode, and gateway config blocks
  • jsz monitoring endpoint now reports leader counts
  • Atomic batch publish supports deduplication with Nats-Msg-Id header

Full Release Notes

## Changelog

Refer to the [2.12 Upgrade Guide](https://docs.nats.io/release-notes/whats_new/whats_new_212) for backwards compatibility notes with 2.11.x.

### Go Version

- 1.25.3 (#7428)

### Dependencies

- github.com/google/go-tpm v0.9.6 (#7374)
- github.com/nats-io/nats.go v1.46.0 (#7374)
- golang.org/x/crypto v0.43.0 (#7423)
- golang.org/x/sys v0.37.0 (#7423)
- golang.org/x/time v0.14.0 (#7423)

### Added

General

- The `NewServerFromConfig` function has been added to the embedded server API for parsing an external configuration file when `ConfigFile` is supplied (#7364)
- WebSocket leafnode connections can now use a HTTP proxy by specifying `proxy` settings in the leafnode `remotes` (#7242)
- The `write_deadline` option in the `cluster`, `leafnode` and `gateway` config blocks allows configuring write deadlines on a finger-grained basis (#7405)

### Improved

Monitoring

- The `jsz` monitoring endpoint can now report leader counts (#7429)

JetStream

- The store lock is no longer held while searching for TTL expiry tasks, improving performance (#7344)
- Removing a message from the TTL state is now faster (#7344)
- The filestore no longer performs heap allocations for hash checks (#7345)
- The filestore now reuses pooled write cache allocations more efficiently (#7346)
- Meta snapshot performance for a very large number of assets has been improved after a regression in v2.11.9 (#7350)
- Sequence-from-timestamp lookups, such as those using `opt_start_time` on consumers or `start_time` on message get requests, now use a binary search for improved lookup performance (#7357)
- Scheduled messages are now deactivated properly when followed up with another message on the same subject without a schedule (#7366)
- Meta snapshots are no longer taken on every stream removal (#7373)
- Filestore cache lookups can now return early for empty blocks (#7381)
- Filestore meta files are now written using temporary staging, avoiding accidental truncation on crashes (#7388)
- Atomic batch publish now supports deduplication with the `Nats-Msg-Id` header (#7391)
- Cache-specific log lines in the filestore have been improved (#7396)
- Log lines and errors related to offline/unsupported assets are now clearer (#7416, #7425)

### Fixed

General

- Fixed the exit code when receiving a `SIGTERM` signal immediately after startup (#7367)
- The `$SYS.REQ.CLAIMS.DELETE` endpoint now correctly strips headers, like the `$SYS.REQ.CLAIMS.UPDATE` endpoint already does (#7413)
- Log lines generated when reloading trusted proxies now report the correct keys (#7427)

JetStream

- Batch check now uses the correct subject instead of the last subject that does the commit (#7342)
- Removed messages with a per-message TTL are now removed from the TTL state immediately (#7344)
- Fixed a bug where TTL state was recovered on startup with subject delete markers enabled, that message expiry would not start as expected (#7344)
- Expiring messages from the filestore no longer leaks timers and expires at the correct time (#7344)
- Fixed a bug where scheduled messages would not trigger correctly after recovery (#7347)
- Deleting a non-existent sequence on a stream no longer results in a cluster reset and leadership election (#7348)
- Subject tree intersection now correctly handles overlapping literals and partial wildcards, i.e. `stream.A` and `stream.*.A`, fixing some consumer or message get filters (#7349)
- A data race when checking all JetStream limits has been fixed (#7356)
- Raft will no longer trigger a reset of the clustered state due to a stream snapshot timeout (#7293)
- Atomic batches now reject unsupported commits (#7368)
- Race conditions and potential panics fixed in the handling of some JetStream API handlers (#7380)
- The filestore no longer loses tombstones when using secure erase (#7384)
- The filestore no longer loses the last sequence when recovering blocks containing only tombstones (#7384)
- The filestore now correctly cleans up empty blocks when selecting the next first block (#7384)
- The filestore now correctly obeys `sync_always` for writing TTL and scheduling state files (#7385)
- The filestore will now correctly expire a cache when the wrong sequence is found (#7396)
- Fixed a data race on a wait group when mirroring streams (#7395)
- Skipped message sequences are now checked for ordering before apply, fixing a potential stream desync on catchups (#7400)
- Skipped message sequences now correctly detect gaps from erased message slots, fixing potential cache issues, slow reads and issues with catchups (#7399, #7401)
- Raft groups now report peer activity more consistently, fixing some cases where asset info and monitoring endpoints may report misleading values after leader changes (#7402)
- Raft groups will no longer permit truncations from unexpected catchup entries if the catchup is completed (#7424)
- The filestore will now correctly release locks when erasing messages returns an error (#7431)

### Complete Changes
 
https://github.com/nats-io/nats-server/compare/v2.12.0...v2.12.1