1.5.72 October 3rd, 2026
Akka.NET v1.5.72 backports a non-blocking Cluster extension startup, test-infrastructure hardening, a Cluster.Sharding hand-over fix, and a batch of de-flaked specs from dev.
Starting with this release, Akka.Hosting ships from this repository. The Akka.Hosting, Akka.Remote.Hosting, Akka.Cluster.Hosting, Akka.Persistence.Hosting, Akka.Hosting.TestKit, and Akka.Hosting.TestKit.Xunit2 packages are now built, tested, and published alongside every Akka.NET release at the same version number.
Akka.Hosting
- Akka.Hosting moves into the akka.net repository - The six Hosting packages now live under
src/contrib/hostingand share the Akka.NET version and release cadence. No package IDs, namespaces, or public APIs changed; bumpAkka.Hosting.*to the same version asAkka.*. Hosting-only hotfix versions (such as1.5.60.1) no longer exist: a Hosting fix ships in the next Akka.NET patch release. The documentation moved to getakka.net/articles/hosting. The akkadotnet/Akka.Hosting repository will be archived and keeps the full commit history and release notes for versions up to 1.5.71; the import was taken from commitcefe3c4c. - Microsoft.Extensions minimum version moves to 10.0 - The
Akka,Akka.DependencyInjectionand allAkka.Hosting.*packages now requireMicrosoft.Extensions.*10.0.0 or later (previously 6.0 for the core packages and 9.0 for Akka.Hosting). The 10.0 packages still shipnetstandard2.0assets, so applications on .NET Framework 4.8, .NET 6 and .NET 8 keep working; NuGet will lift the transitiveMicrosoft.Extensions.*references in those applications to 10.0.x. Akka.Hosting'sOpenTelemetrydependency moves to 1.15.3 or later, which clears GHSA-g94r-2vxg-569j.
Akka.TestKit / Akka.TestKit.Xunit
- TestKit.Xunit: implement the async dispose chain -
Akka.TestKit.Xunit.TestKitnow implementsInitializeAsync/DisposeAsyncdirectly instead of relying on a derived class's own no-op overrides. Breaking change: a derived spec that already declares its ownInitializeAsync/DisposeAsyncmust mark themoverrideand call the base method, or the build fails withCS0114.Dispose(bool)no longer terminates theActorSystemby itself; the publicDispose()/DisposeAsync()entry points do, after calling the base chain. - Put the DotNetty batching override under akka.remote - The TestKit's write-batching override now lands under the key the transport actually reads. Every TestKit-hosted and multi-node test system runs with DotNetty write batching genuinely off for the first time.
- Add TestKitBase.ShutdownAsync - New public
TestKitBase.ShutdownAsyncoverloads shut anActorSystemdown without blocking a thread pool worker. - Eliminate the MultiNodeTestRunner conductor port race - The conductor node now binds port 0 and reports the real port over a stdout sentinel, instead of guessing a free port in advance, removing a race that could leave every other node waiting out a timeout against a conductor that never started. Adds the public
ConductorBindExceptionandConductorPortSentineltypes, and a 20-minute backstop that kills a node process that never exits on its own.
Akka.Streams
- Tcp Unbind completes immediately when idle -
ServerBinding.Unbind()used to always wait out the subscription timeout even when no connection was pending. It now completes right away in that case, and still correctly waits when a connection was accepted but never subscribed to.
Akka.Cluster.Sharding
- Arm the remember-entities write timeout with updating-state-timeout - Remember-entities writes are now timed against
updating-state-timeout(5 seconds by default), matching whatreference.confalways documented, instead ofwaiting-for-state-timeout(2 seconds). Migration: if you raisedwaiting-for-state-timeoutto give a slow remember-entities store more time, move that value toupdating-state-timeoutinstead - it no longer affects the write path. - A coordinator hand-over only stops the local ShardRegion when the node is leaving - Fixes #8583: a routine singleton hand-over during a rolling restart no longer stops a
ShardRegionthat isn't leaving the cluster, which used to leave that region permanently unusable for the life of the process.
Akka.DistributedData
- Fix Replicator.IsKnownNode to trust members first seen as Leaving/Exiting/Downed - A
Replicatorstarted after a member had already begun leaving no longer silently drops that member's writes and gossip.
Akka.Cluster
- Prevent removed cluster members from being resurrected by stale gossip - Gossip now carries UID-scoped removal tombstones and retains them for 24 hours by default (
akka.cluster.prune-gossip-tombstones-after). The wire change is rolling-upgrade compatible: older nodes ignore the added protobuf field and upgraded nodes treat its absence as an empty tombstone set. Protection becomes fully effective after every node is upgraded; removals that occur while old nodes remain in the cluster are not guaranteed to retain their tombstones. - Akka.Cluster: make Cluster extension startup non-blocking - The
Clusterconstructor no longer blocks on a 20 second ask, andakka.actor.creation-timeoutis no longer consulted by Akka.Cluster at all (Akka.Cluster.Sharding still uses it to bound its own start-up asks). This removes the "Failed to startup Cluster" failure mode, which could shut down a healthy node whenever every thread the startup needed was parked - a small fork-join or other dedicated dispatcher pool, or a stock pool starved under load. Behavior note:Cluster.Get()now returns before core initialization completes, and the cluster's internal actor tree (/system/cluster/core,/system/cluster/core/daemon,/system/cluster/heartbeatReceiver) is created afterCluster.Get()returns rather than before it. All public cluster APIs are message-based, so typical code is unaffected; code that usedCluster.Get()as a "core is started" synchronization point, or that resolves one of those internal paths right after obtaining the extension, should awaitJoinAsync/RegisterOnMemberUpor a cluster event instead. - Akka.Cluster: route user commands through /system/cluster for the extension's lifetime; LeaveAsync re-sends its Leave - All user-issued cluster commands (
Subscribe,Join,Leave,Down, ...) now route through/system/clusterfor the entire lifetime of the extension - two extra local mailbox hops on this low-traffic control plane - instead of switching to a direct core-daemon reference once startup resolves one, so back-to-back commands from one caller stay in order for good, not just during startup. A lostLeaveno longer wedges every laterLeaveAsync()for the life of the process. Behavior note: callingLeave()/LeaveAsync()again after the extension has already shut down now produces a dead-letteredClusterUserAction.Leave- worth knowing about for dead-letter alerting orEventFilter.DeadLetterassertions.
Testing
- Bugfix5962Spec de-flaked for the non-blocking cluster startup - the spec's raw 1 second
ResolveOneagainst/system/cluster/core/daemon/downingProviderraced the async cluster-extension init #8359 introduces above; replaced with a dilated retrying resolve, a dynamic port, and an asyncTaskCompletionSourcemember-up signal. - De-flaked a large batch of Cluster, Cluster.Sharding, Cluster.Tools, DistributedData, Streams, and Remote specs, both single-process and multi-node, to remove timing-sensitive failures under load.
3 contributors since release 1.5.71
| COMMITS | LOC+ | LOC- | AUTHOR |
|---|---|---|---|
| 66 | 35268 | 2030 | Aaron Stannard |
| 1 | 94 | 47 | Bojan Janjatović |
| 1 | 2 | 1 | Matt Kotsenas |
To see the full set of changes in Akka.NET v1.5.72, click here.
Changes:
- 5cb76a8 Merge pull request #8741 from Aaronontheweb/release/v1.5.72
- 4590040 Bump version to 1.5.72 and update release notes
- 36c2837 Merge pull request #8722 from Aaronontheweb/backport/dev-2026-10-to-v1.5
- 57066dc Rerun CI after ActorTelemetry timing flake
- 90e4463 Preserve v1.5 ConsistentHash nullability metadata
- 7cf147b Fix graceful close spec on .NET Framework
- a8300e5 Warn about v1.5 explicit hostname limitation
- 63742e9 v1.5: adapt cryptographic seeding and graceful close to library TFMs
- 0ee2509 DistributedData: remove ReplicatorMessageSerializer's dead cache and its leaked timer (#8643) (#8699)
- 2a24569 De-flake ThrottlerManagerLifecycleSpec: wait for the manager's own Terminated before SetThrottle (#8708)
See More
- a2ac7e7 Disassociate the wrapped handle when a throttled association stops (#8637) (#8647)
- feaab95 Classic remoting: half-close on disassociate so a Windows peer doesn't lose our last frames to an RST (#8635) [ #8589 ]
- e3685f3 Akka.Streams: fix a possible lost wakeup in MergeHub (missing memory fence) (#8665)
- 4a0e4a7 Seed ThreadLocalRandom from a cryptographic source (#8377)
- 4d2c815 Fix stack overflow deserializing ISurrogated-typed members without $type metadata (#8358) [ #6502, #6503, #8354 ]
- 9eb31dc perf: stop retaining ConsistentHash ring's SortedDictionary (#8293) (#8324)
- 72d3eda Add missing HasValue guard for CpuTotalUsage metric in Sample() (#8066)
- 7cda7b6 Fix MemoryUsed metric failing due to .NET runtime bug
- 8c66934 Fix SQLitePCLRaw CVE-2025-6965 in example projects (#8735)
- 5aeed9a Backport gossip removal tombstones to v1.5 (#8723) [ #8484 ]
- 3e02c10 Cluster.Metrics: fix nested selector manifest so remote-deployed adaptive pools deserialize (v1.5 backport) (#8705) [ #8704 ]
- 749513e Akka.Cluster: a Down node must never be leader, so it can't remove itself and linger outside the cluster (#8650)
- 84da585 v1.5: move Akka.Hosting into the akka.net repository (#8591) [ akkadotnet/Akka.Hosting#663 ]
- 9d659bd Merge pull request #8588 from akkadotnet/backport/dev-2026-09-to-v1.5
- ef1e761 v1.5: collect a hang dump and the in-progress test list when a net10.0 unit-test host hangs
- 8ab2713 v1.5: fix net48 build breaks from the #8359/#8398 cherry-picks
- 632a3d5 v1.5: release notes for the September backport [ #8574, #8359, #8580, #8398 ]
- 610328a v1.5: add a discriminating ClusterSpec fact for LeaveSelf's re-send [ #8580 ]
- 09ea8a1 v1.5: allow the multi-node pipeline template to pass env, run StressSpec at 7 nodes [ #8553 ]
- 3439a42 v1.5: reword backported test comments for classic remoting and the StressSpec node-count doc [ #8579, #8359, #8580 ]
- 3dbc510 v1.5: StressSpec churn phase - abrupt removal budget and async teardown (port of #8543) [ #8372, #8427, #8429, #8499, #8515 ]
- e4cf191 v1.5: fix Process.Kill(bool) call from the #8515 hand-merge (netstandard2.0 has no process-tree kill overload) [ #8431 ]
- a285d8b v1.5: regenerate TestKit API approvals for ShutdownAsync [ #8499 ]
- 658fee0 v1.5: remove Artery-only configuration from backported specs [ #8552 ]
- e8575a8 v1.5: drop BREAKING_CHANGES_V1.6.md brought in by cherry-picks [ #8545 ]
- 406df55 De-flake Bugfix5962Spec: dilated async waits, dynamic port, async TCS member-up signal (#8398) [ #5962 ]
- cb61808 Cluster: route user commands through /system/cluster for the extension's lifetime so their order survives startup; LeaveAsync re-sends its Leave (#8580)
- b593e27 Akka.Cluster: make Cluster extension startup non-blocking (fixes StressSpec CI deadlock) (#8359)
- 81382be De-flake RemoteNodeRestartDeathWatchSpec: out-wait the association gate (#8404)
- 2539565 De-flake NodeChurnSpec: turn off legacy auto-down, widen the heartbeat pause over the measured stall, and make the payload listener match real log messages (#8556) [ #8549 ]
- 805e6c1 De-flake RemoteNodeDeathWatchSpec: barrier after the subject stops, resend-derived bound, identify asserts the actor exists (#8581)
- 212cdbe De-flake ClusterSingletonManagerLeave2Spec: watch the proxy from a dedicated probe, as upstream does; migrate the file to the async TestKit API (#8569)
- 7c16638 De-flake ClusterDeathWatchSpec: resolve first's end actor over the return lane before sending End (#8563)
- 82d3b11 De-flake ClusterShardingRegistrationCoordinatedShutdownSpec: wait on the spec's own budget instead of a probe's flat 5 s default (#8544)
- 8f1d660 De-flake RemoteDeliverySpec: give the final barrier a budget that covers the loop (#8542)
- a971497 De-flake DistributedPubSubRestartSpec: the restarted node makes first contact, and the survivor waits on it (#8552) [ #8557 ]
- 889b3e0 Wave-3 de-flake: ReplicatorChaosSpec, ClusterShardingLeavingSpec pin, DistributedPubSubRestartSpec baseline (#8509) [ #8481, #8500, #8498 ]
- 1a12cb0 De-flake ClusterShardingSpec family: re-send Gets that race shard hand-off (#8500)
- 9742cd6 De-flake ClusterSingletonProxySpec, ClusterSingletonRestartSpec, and DistributedPubSubRestartSpec (#8498)
- 18e3dfe De-flake ShardingBufferAdapterSpec: re-send the cold messages with a fresh probe per attempt under a sharding-derived budget (#8573) [ #8545 ]
- a1984bf De-flake EntityTerminationSpec: anchor on the shard's own entity set and wait out the restart backoff without blocking a pool thread (#8584)
- 75aa3cd De-flake InboxSpec: receive through ReceiveAsync so a deadline failure surfaces as TimeoutException (#8564)
- fd6755d De-flake PropsSpec: await the producer latch instead of blocking on it for a flat second (#8587)
- e146933 De-flake BugFix3724Spec and HubSpec: give the zero-count event filter its own 3 s window instead of the Within's remaining time (#8566) [ #8516 ]
- 10fb40d De-flake ReceiveTimeoutSpec: measure the two timeout cycles with dilated probe waits instead of one flat latch (#8541)
- 43835bb De-flake ClusterSpec leave facts: await MemberUp before leaving so the join is ordered first; one leader pass, then MemberRemoved (#8579)
- 6699d32 De-flake ClusterSpec: stop passing an already-cancelled token to its WithinAsync block (#8540)
- 736db10 TestKit.Xunit: implement the async dispose chain so a derived DisposeAsync no longer leaks the ActorSystem; de-flake StreamRefsSpec (#8545) [ #8191, #8217 ]
- 0484512 De-flake ClusterShardingLeaseSpec: join the cluster in InitializeAsync instead of blocking a pool worker in the constructor (#8558)
- 8134ace MNTR: eliminate the conductor port race - bind port 0 and propagate via stdout sentinel (#8515) [ #8431, #8492 ]
- f1dd241 TestKit: put the DotNetty batching override under akka.remote, where the transport reads it (re-land of #8546 with the RemoteConfigSpec fix) (#8561)
- b98e9ac Cluster.Sharding: a coordinator hand-over only stops the local ShardRegion when the node is leaving (#8586) [ #8583 ]
- e75b51b Fix Replicator.IsKnownNode to trust members first seen as Leaving/Exiting/Downed (#8582)
- 11daf6e Cluster.Sharding: arm the remember-entities write timeout with updating-state-timeout, as the config documents (#8574) [ #6479 ]
- e8ce8b1 Akka.Streams: Tcp Unbind completes at once when no connection is awaiting initialization; the counter was seeded at -1 (#8570)
- 6435db9 fix: migrate NodeChurnSpec to async TestKit APIs to fix shutdown-timeout flakiness (#8286)
- 7cfbbde De-flake ClusterShardingSpec recovery phase: keep barriers out of Within (#8406)
- 34b937c Add TestKitBase.ShutdownAsync and adopt it in StressSpec churn teardown (#8499) [ #8497 ]
- d9d6331 TestKit: WithinAsync no longer swallows the block's failure when the deadline wins (#8516) (#8529) [ #8483 ]
- 8d68f3f De-flake ClusterShardingQueriesSpec: wait for all regions to register before triggering allocation (#8524) (#8539)
- afa36fc fix: bump Microsoft.SourceLink.GitHub to 10.0.303 to clear NU1902 (CVE-2026-62900) (#8548)
- 3772d83 Fix #8508: arm ClusterClient's reconnect deadline per establishing phase, not per message (#8510) (#8511)
- b81a46d MNTR: make barrier failures actually fail the barrier (#8431) (#8492) [ #8488 ]
This list of changes was auto generated.