## 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 ### Dependencies - github.com/klauspost/compress v1.19.2 (#8459) - golang.org/x/crypto v0.55.0 (#8459) ### Added Leafnodes - New `dia
## Changelog ### Go Version - 1.25.12 ### Dependencies - github.com/klauspost/compress v1.19.2 (#8459) - golang.org/x/crypto v0.55.0 (#8459) ### Fixed General - Fixed a deadlock that could occur in the logger when a close error occurs (#8430) JetStream - Fix a bug that could result in potential data loss when handling idempotent stream creates when an offlin
## Changelog ### Go Version - 1.25.12 ### Dependencies - github.com/klauspost/compress v1.19.2 (#8459) - golang.org/x/crypto v0.55.0 (#8459) ### Fixed General - Fixed a deadlock that could occur in the logger when a close error occurs (#8430) JetStream - Fix a bug that could result in potential data loss when handling idempotent stream creates when an offlin
## 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 ### Dependencies - github.com/klauspost/compress v1.19.2 (#8459) - golang.org/x/crypto v0.55.0 (#8459) ### Added Leafnodes - New `dia
Previously if you started sourcing from a stream that was recreated, it would wait for the recreated stream's sequence to move back up to the last sourced sequence before it accepted new messages. This PR detects a stream being recreated by noticing a changed `Nats-Stream-Identity`, which is the hash of the stream's created time. There exists no unique ident
### Observed behavior We have a JetStream deployment where a destination stream sources data from many remote JetStream domains using external stream sources. For one source, after the source stream was recreated, the destination stream stopped ingesting new messages from that source. However, stream info continues to report: lag: 0 no error non-zero active
### Proposed change Add a `--keep-last-msg-per-subject` flag to the nats server configuration i.e. `nats stream add --keep-last-msg-per-subject <more-options> <stream>` that works with all limits-based message retention policies (i.e time-based, size-based, count-based). ### Use case Stream limits options (e.g. `max-age`, `max-bytes`, `max-msgs` etc.) mostly
### Observed behavior Setup: basic hub spoke with leafnodes. hub is a single jetstream enabled server in its own domain, so are the leaf nodes. On the hub, there is a stream named match_events that sources from the match_events stream in each leaf node. Symptoms: Sourcing from match_events on one leafnode stopped working. Despite new messages being added to
Add websocket `proxy_protocol` support by parsing optional PROXY headers on the raw listener before TLS and HTTP upgrade processing. Non-proxied websocket clients continue to work because pre-read bytes are replayed into the next protocol layer, and the setting is exposed in `/varz`. Validation: - `go test -v ./server -run '^(TestWSParseOptions|TestWSProxyPr
The retention and placement from the stream's config must always return the latest state the user requested, and the desired state contains the 'origin' if needed. Before this PR the stream would already keep running under Limits if it was updated to Interest retention, since this allows the consumers to be scaled up to have parity with the stream's replicat
Recovered v4 file-store blocks now reach the range validator. It learns timestamp order before it selects an eligible MaxAge prefix. Cold upgraded stores can remove complete expired blocks with one range update instead of one removal per message. The repair also reuses the existing `selectNextFirst` owner after prefix removal. This removes leading empty bloc
This PR adds initial support for desired state reconciliation of stream and consumer updates that change the peer set. These, and follow-up, changes intend to fix loads of related issues surrounding peer set management of assets. For example, including but not limited to: a scale down not being guaranteed to select the right leader or servers with all data t
`syncBlocks` should leave all message blocks synced after it returns. This was not always the case when a block needed compaction during the same pass. Specifically, if the block was initially marked as not needing sync, i.e. `mb.needSync = false`, then `syncBlocks` would miss the fact that `compactWithFloor` could later set `mb.needSync = true` on that same
The move and cancel move endpoints are now wired fully through desired state. The cancel move endpoint can now be reliably used; the first move (either through stream updates or the move endpoint) initialize the "origin" which is the peer set and config (replicas, placement and retention) at that time, multiple moves or scales could technically be run even b
Includes the following: - https://github.com/nats-io/nats-server/pull/8430 - https://github.com/nats-io/nats-server/pull/8449 - https://github.com/nats-io/nats-server/pull/8454
This PR wires peer removals and additions into desired state. - `reconcilePeerAssignments` runs on a meta leader change, so proposals that were missed or only partially applied can be retried by the next leader. - Peer additions through `processAddPeer` now also obey the rules of `cc.selectPeerGroup`, which requires waiting for STATSZ info if it isn't yet av
If a stream/consumer Raft group was below quorum, it wasn't possible to safely peer-remove nodes to get into quorum again. This PR fixes that by allowing nodes to be evicted when below quorum, but only those nodes that were explicitly peer-removed. Given a R3 stream without quorum due to 2 nodes being offline, it's now possible to peer-remove those two offli
This PR fixes two remaining issues, and removes the final two FIXMEs: - Migrations would add peers as fast as possible, without checking whether the peer being added was even online. Adding an offline peer grows the quorum size, which could drop the group out of quorum until enough nodes came online. `selectPeerToAdd` now prefers the candidate we've heard fr