NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
NuGet · #2776 most downloaded on NuGet
JetStream persistent messaging for NATS .NET. Provides at-least-once delivery, stream management, and pull/push consumers for durable message processing.
Last release 8 days ago
30 Sep 2026
Ships fairly regularly
a new release about every 3 weeks
Rarely documented
notes for 7 of 60 stable releases
Nothing withdrawn
no release was ever pulled
3 years old
60 releases · first in 2023
Breaking for implementers: INatsJSContext , INatsJSStream and INatsSvcServer gained members (push consumer creation and RemoveEndpointAsync ). Anythin
Breaking for implementers: INatsJSContext, INatsJSStream and INatsSvcServer gained members (push consumer creation and RemoveEndpointAsync). Anything implementing these interfaces directly, such as a test double, needs updating. Callers are unaffected. Default implementations are not possible while the client targets netstandard2.0.
New:
INatsJSPushConsumer, NatsJSPushConsumerOpts and CreatePushConsumerAsync, CreateOrUpdatePushConsumerAsync, GetPushConsumerAsync and CreateOrderedPushConsumerAsync on the JetStream context and stream. Pull operations on a push consumer throw NatsJSProtocolException (#1231)NatsOpts.CaseSensitiveHeaders. Headers stay case-insensitive by default (#1258)INatsSvcServer.RemoveEndpointAsync (#1255)NatsJsonSerializer accepts JsonWriterOptions alongside JsonSerializerOptions (#1253)NatsKVPurgeOpts.RetainRecentlyDeletedKeyHistory keeps the history of recently deleted keys when purging delete markers (#1252)Fixed:
AllowDirect disabled: GetEntryAsync with a revision threw "Unexpected subject", and deleted or purged keys came back as live Put entries (#1240)Thanks to @Ivandemidov00 for the push consumer API, @adamjones2 for the service endpoint, serializer and KV purge changes, @jeacott1 for the header handling, and @fresh55 for reporting and fixing the KV read bug.
One column per month.
Breaking for implementers: INatsJSStream and INatsJSConsumer gained members ( ResetConsumerAsync , ResetAsync ). Anything implementing these interface
Breaking for implementers: INatsJSStream and INatsJSConsumer gained members (ResetConsumerAsync, ResetAsync). Anything implementing these interfaces directly, such as a test double, needs updating. Callers are unaffected. Default implementations are not possible while the client targets netstandard2.0.
JetStream parity with server 2.14:
missing list (#1248)ConsumerConfig.Sourcing exposes the flag the server sets on consumers it creates for interest and work queue stream sourcing (#1249)Patch release on top of 3.1.0, promoting 3.1.1-preview.1 to stable. Most of it is the OpenTelemetry receive path. Receive spans for messages consumed
Patch release on top of 3.1.0, promoting 3.1.1-preview.1 to stable. Most of it is the OpenTelemetry receive path. Receive spans for messages consumed internally by the Key/Value watcher, the ordered push consumer behind the Object Store and service endpoints were never ended, so they never reached a backend; shared-inbox request-reply produced disconnected traces with no request span; a JetStream direct get was traced under the write that stored the value rather than the read; and several span tags were wrong. Also fixes a null array passed on the netstandard2.0 object store put path, and a stall when TCP splits the trailing CRLF of an empty payload message.
Three changes in #1236 are visible in a tracing backend, so queries and dashboards built on the client's spans may need updating: messaging.operation on subscribe and request spans now reads subscribe and request rather than publish, the subscribe span is ActivityKind.Client rather than Producer, and a reply whose trace id differs from its request is linked rather than parented.
Full Changelog: v3.1.0...v3.1.1
Minor release on top of 3.0.1. Adds subscription events with an OnSubscribed callback, enables full-graph NuGet dependency auditing, and adds document
Minor release on top of 3.0.1. Adds subscription events with an OnSubscribed callback, enables full-graph NuGet dependency auditing, and adds documentation examples.
The async enumerable returned by SubscribeAsync does not establish the subscription until it is iterated. When the enumerable is handed off to another task, the new OnSubscribed callback signals when it is safe to publish messages the subscription must observe:
var subscribed = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var opts = new NatsSubOpts
{
Events = new NatsSubEvents
{
OnSubscribed = _ =>
{
subscribed.TrySetResult();
return default;
},
},
};
var consumer = Task.Run(async () =>
{
await foreach (var msg in nats.SubscribeAsync<string>("greet", opts: opts))
{
// process messages
}
});
await subscribed.Task;
await nats.PublishAsync("greet", "hello"); // subscription is establishedOnSubscribed fires once the SUB protocol message has been queued on the subscribing connection, which is enough when publishing on the same connection. If the publisher uses a different connection, add a PingAsync round-trip on the subscribing connection after the callback to be sure the server has processed the subscription:
await subscribed.Task;
await nats.PingAsync(); // server has processed the SUB
await otherConnection.PublishAsync("greet", "hello");Patch release on top of 3.0.0. Fixes a JetStream list enumeration cancellation bug and adds opt-in W3C Baggage propagation to the OpenTelemetry integr
Patch release on top of 3.0.0. Fixes a JetStream list enumeration cancellation bug and adds opt-in W3C Baggage propagation to the OpenTelemetry integration.
Deprecate SkipSubjectValidation #1180
NATS .NET 3.0 is now stable. This release has been in the works since early this year and brings OpenTelemetry tracing and metrics, .NET 10 target, and a number of API and behavior changes refined over the preview series. Thanks to everyone who tried the previews and reported issues along the way. There are no changes since 3.0.0-preview.11.
3.0 targets netstandard2.0, netstandard2.1, net8.0, and net10.0. net6.0 has been dropped.
Thanks to the community for the contributions and issue reports behind this release:
Details of the API and behavior changes, with the preview each first shipped in.
net6.0 is dropped and net10.0 added; the full set is netstandard2.0, netstandard2.1, net8.0, net10.0. Apps targeting .NET 6 or 7 keep working through the netstandard2.1 build, whose encoding hot paths were optimized in 3.0 (#1072), but .NET 8+ gets the fastest code paths.
NatsOpts.RequestReplyMode now defaults to NatsRequestReplyMode.Direct: replies are correlated through the connection's existing inbox subscription instead of setting up a subscription and channel per request. Semantics are unchanged, including ThrowIfNoResponders. To restore the previous behavior:
var opts = new NatsOpts { RequestReplyMode = NatsRequestReplyMode.SharedInbox };All entry points (NatsConnection, NatsClient, DI builders) now share the NatsOpts defaults: pending channel capacity 16384 (up from 1024) and BoundedChannelFullMode.DropNewest. Previously NatsClient and the DI builders forced Wait, which can stall the socket read loop and get the client disconnected as a slow consumer. If a subscriber now falls behind by more than 16K messages, the newest messages are dropped and surfaced through MessageDropped instead of blocking. To restore blocking, accepting the slow consumer risk:
var opts = new NatsOpts { SubPendingChannelFullMode = BoundedChannelFullMode.Wait };The option still works but produces a compiler warning. Validation costs 0-5% on a publish microbenchmark and prevents silently misrouted messages: a subject containing a space splits into subject and reply-to tokens on the wire with no error.
New opt-in INatsSerializeWithContext<T>, INatsDeserializeWithContext<T>, and INatsSerializerWithContext<T> interfaces receive a NatsMsgContext (subject, reply-to, headers) during (de)serialization. Existing serializers work unchanged. One side effect: NatsHeaders no longer becomes read-only after publish, so a single NatsHeaders instance should not be shared across concurrent publishes.
INatsSocketConnection and INatsTlsUpgradeableSocketConnection moved to the NATS.Client.Abstractions package so custom transports can implement them without referencing Core. The namespace is unchanged and the types are forwarded, so existing code is source and binary compatible.
The new NATS.Client.OpenTelemetry package adds AddNatsClientInstrumentation() extensions for both TracerProviderBuilder and MeterProviderBuilder, with options for subject filtering and custom span destination names.
using NATS.Client.OpenTelemetry;
services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddNatsClientInstrumentation(opts => opts.FilterSubjects(exclude: ["_INBOX.>"])))
.WithMetrics(metrics => metrics
.AddNatsClientInstrumentation());INatsSub<T>.DrainAsync() drains a single subscription without disposing the connection: no new deliveries, in-flight messages fenced with a PING/PONG, channel completed.
var sub = await nats.SubscribeCoreAsync<Order>("orders.>");
// ... read from sub.Msgs ...
await sub.DrainAsync(); // in-flight messages still delivered, connection stays openFor JetStream consume loops, the opt-in DrainOnCancel consume option delivers buffered messages after cancellation so handlers can still ack; the default keeps the previous stop-immediately behavior.
var opts = new NatsJSConsumeOpts { DrainOnCancel = true };
await foreach (var msg in consumer.ConsumeAsync<Order>(opts: opts, cancellationToken: ct))
{
await msg.AckAsync();
}
// on cancellation the loop drains: stops pulling, delivers buffered messages, then completesNATS.Extensions.Microsoft.DependencyInjection now depends on NATS.Client.Simplified instead of the all-inclusive NATS.Net, and NATS.Net now includes the DI package. If you referenced only the DI package and used JetStream, Key-Value, Object Store, or Services through its transitive dependency, add a direct NATS.Net reference (or the specific packages you use).
Full Changelog: v2.8.2...v3.0.0
Patch release on the 2.8 line. Fixes ordered push consumer subscription teardown. Thanks to @haoguanjun for the fix.
Patch release on the 2.8 line. Fixes ordered push consumer subscription teardown. Thanks to @haoguanjun for the fix.
Full Changelog: v2.8.1...v2.8.2
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →