v2.12.4

nats-io/nats-serverv2.12.4Jan 27, 2026by github-actions[bot]

AI Summary

Patch release for NATS server v2.12.x focusing on JetStream bug fixes, performance improvements, and dependency updates. Includes a new TLS certificate expiration monitoring endpoint.

Key Highlights

  • Go version updated to 1.25.6
  • Added `tls_cert_not_after` to varz monitoring endpoint for TLS certificate expiration tracking
  • Multiple JetStream performance improvements including consumer creation and num pending calculations
  • Fixed numerous Raft election and leadership issues in clustered JetStream
  • Fixed data races and concurrent access issues in JetStream filestore

New Features

  • TLS certificate expiration monitoring via `tls_cert_not_after` in varz endpoint
  • WebSocket ping interval configuration via `ping_internal` (backported from v2.11)

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.6 (#7736)

### Dependencies

- github.com/google/go-tpm v0.9.8 (#7696)
- github.com/nats-io/nats.go v1.48.0 (#7696)
- github.com/klauspost/compress v1.18.3 (#7736)
- golang.org/x/crypto v0.47.0 (#7736)
- golang.org/x/sys v0.40.0 (#7736)

### Added

Monitoring

- Added `tls_cert_not_after` to the `varz` monitoring endpoint for showing when TLS certificates are due to expire (#7709)

### Improved

JetStream

- Creating consumer file stores no longer contends on the stream lock, improving consumer create performance on heavily loaded streams (#7700)
- Recalculating num pending with updated filter subjects no longer gathers and sorts the subject filter list twice (#7772)
- Switching to interest-based retention will now remove no-interest messages from the head of the stream (#7766)

### Fixed

General

- The config parser now correctly detects and errors on self-referencing environment variables (#7737)
- Internal functions for handling headers should no longer corrupt message bodies if appended (#7752)

JetStream

- Raft single node elections now transition into leader state correctly (#7642)
- R1 streams will no longer incorrectly drift last sequence when exceeding limits (#7658)
- Deleted streams are no longer wrongfully revived if stalled on an upper-layer catchup (#7668)
- A panic that could happen when receiving a shutdown signal while JetStream is still starting up has been fixed (#7683)
- JetStream usage stats now correctly reflect purged whole blocks when optimising large purges (#7685)
- Recovering JetStream encryption keys now happens independently of the stream index recovery, fixing some cases where the key could be reset unexpectedly if the index is rebuilt (#7678)
- Non-replicated file-based consumers now detect corrupted state on disk and are deleted automatically (#7691)
- A panic that could occur when a compact and a hash check run concurrently on a store has been fixed (#7697)
- Raft no longer allows a repeat vote for the same term after a stepdown or leadership transfer (#7698)
- Replicated consumers are no longer incorrectly deleted if they become leader just as JetStream is about to shut down (#7699)
- Fixed an issue where a single truncated block could prevent storing new messages in the filestore (#7704)
- Fixed a concurrent map iteration/write panic that could occur on WorkQueue streams during partitioning (#7708)
- Fixed a deadlock that could occur on shutdown when adding streams (#7710)
- Required API level errors are now only returned after other checks, preventing unexpected replies from other servers (#7711)
- A data race on mirror consumers has been fixed (#7716)
- JetStream no longer leaks subscriptions in a cluster when a stream import/export is set up that overlaps the `$JS.>` namespace (#7720)
- The filestore will no longer waste CPU time rebuilding subject state for WALs (#7721)
- Configuring `cluster_traffic` in config mode has been fixed (#7723)
- Subject intersection no longer misses certain subjects with specific patterns of overlapping filters, which could affect consumers, num pending calculations etc (#7728, #7741, #7744, #7745)
- Multi-filtered next message lookups in the filestore can now skip blocks when faster to do so (#7750)
- The binary search for start times now handles deleted messages correctly (#7751)
- Consumer updates will now only recalculate num pending when the filter subjects are changed (#7753)
- Consumer info calls will no longer recalculate num pending (#7758)
- Consumers on replicated interest or workqueue streams should no longer lose interest or cause desyncs after having their filter subjects updated (#7773)
- Interest-based streams will no longer start more check interest state goroutines when there are existing running ones (#7769)

### Complete Changes
 
https://github.com/nats-io/nats-server/compare/v2.12.3...v2.12.4