dotnet/aspnetcore · error · RuntimeException
Trying to send and message while the connection is not…
Error message
Trying to send and message while the connection is not active.
What it means
sendHubMessageWithLock is the internal dispatch used by the public invoke/send/stream paths after they have built the HubMessage. It re-checks the state under the lock because the state may have transitioned away from CONNECTED between the caller's check and the actual transport.send. The message text contains a typo ('send and message').
Solutions
- Retry the invocation after the connection is re-established (subscribe to onReconnected).
- Serialize invocations through a single queue drained only when state == CONNECTED so the window cannot open.
- Avoid calling stop() concurrently with outstanding invocations - drain them first or let them fail fast.
Example fix
// before
hub.invoke("M").subscribe(...);
// concurrently on another thread:
hub.stop();
// after - stop only after invocations drain
hub.invoke("M").await();
hub.stop().await(); Defensive patterns
Strategy: retry
Try / catch
// This is an internal send; treat any 'connection is not active' failure
// from invoke/send/stream as recoverable.
try {
hub.invoke("M").await();
} catch (RuntimeException e) {
if (e.getMessage().contains("connection is not active")) {
// wait for onReconnected, then retry once
} else throw e;
} Prevention
- Do not call stop() concurrently with outstanding invocations.
- Drain or cancel in-flight invocations before stop().
- Use a single-threaded outbound queue to eliminate the race window.
When it happens
Trigger: The connection drops between the outer invoke/send state check and this inner send: a close/transport-error callback fires on another thread and moves the state to DISCONNECTED before sendHubMessageWithLock acquires the lock.
Common situations: High-concurrency invoke during an unstable network; server-initiated close arriving while a burst of invocations is queued; stop() called concurrently with invoke() on another thread.
Related errors
- The 'invoke' method cannot be called if the connection is…
- The 'send' method cannot be called if the connection is not…
- The 'stream' method cannot be called if the connection is…
- Connection is not active.
- The HubConnection failed to transition from the
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/1cf8c08b74c62329.
Report an issue: GitHub.
Appendix: source
Thrown at src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/HubConnection.java:828
sendInvocationMessage(method, args, invocationId, true);
return observable.doOnDispose(() -> {
if (subscriptionCount.decrementAndGet() == 0) {
CancelInvocationMessage cancelInvocationMessage = new CancelInvocationMessage(null, invocationId);
sendHubMessageWithLock(cancelInvocationMessage);
connectionState.tryRemoveInvocation(invocationId);
subject.onComplete();
}
});
} finally {
this.state.unlock();
}
}
private void sendHubMessageWithLock(HubMessage message) {
this.state.lock();
try {
if (this.state.getHubConnectionState() != HubConnectionState.CONNECTED) {
throw new RuntimeException("Trying to send and message while the connection is not active.");
}
ByteBuffer serializedMessage = protocol.writeMessage(message);
if (message.getMessageType() == HubMessageType.INVOCATION) {
logger.debug("Sending {} message '{}'.", message.getMessageType().name(), ((InvocationMessage)message).getInvocationId());
} else if (message.getMessageType() == HubMessageType.STREAM_INVOCATION) {
logger.debug("Sending {} message '{}'.", message.getMessageType().name(), ((StreamInvocationMessage)message).getInvocationId());
} else {
logger.debug("Sending {} message.", message.getMessageType().name());
}
ConnectionState connectionState = this.state.getConnectionStateUnsynchronized(false);
connectionState.transport.send(serializedMessage).subscribeWith(CompletableSubject.create());
connectionState.resetKeepAlive();
} finally {
this.state.unlock();
}
}
View on GitHub (pinned to 3600ca084e)