@@ -103,10 +103,12 @@ public void Dispatch(ITcpTransportEvent evt)
103103
104104 public void HandlePush ( IOutputItem item )
105105 {
106- // Auto-connect: on the first item (any type), derive connection parameters
107- // from the item's endpoint and acquire a connection.
108- if ( _handle is null && _pendingConnect is null && item . Key . Scheme is not null &&
109- item . Key != RequestEndpoint . Default )
106+ // Auto-connect: on the first data/control item, derive connection parameters
107+ // from the item's endpoint and acquire a connection. Skip ConnectItem — it
108+ // handles its own acquisition in HandleConnectItem and running AutoConnect
109+ // first would start a duplicate acquire that races with the real one.
110+ if ( _handle is null && _pendingConnect is null && item is not ConnectItem &&
111+ item . Key . Scheme is not null && item . Key != RequestEndpoint . Default )
110112 {
111113 AutoConnect ( item . Key ) ;
112114 }
@@ -359,6 +361,15 @@ private void OnOutboundWriteFailed(Exception ex)
359361
360362 private void OnAcquisitionFailed ( Exception ex )
361363 {
364+ // Ignore cancellations from a previous acquisition that we explicitly
365+ // cancelled (e.g. CleanupTransport cancelled the old CTS). Processing
366+ // this would corrupt the _pendingConnect of a newer, valid acquisition.
367+ if ( ex is OperationCanceledException )
368+ {
369+ _ops . Log . Debug ( "TcpConnectionStage: AcquisitionFailed (cancelled) — ignored" ) ;
370+ return ;
371+ }
372+
362373 _ops . OnCancelTimer ( ConnectTimerKey ) ;
363374
364375 if ( _waitActivity is not null )
0 commit comments