dotnet/aspnetcore · error · RuntimeException

Connection is not active.

Error message

Connection is not active.

What it means

A RuntimeException thrown by ReconnectingConnectionState.getConnectionStateUnsynchronized when allowNull is false (i.e. the caller requires an active connection) but the internal ConnectionState field is null. This indicates the HubConnection is not active (never started or already stopped) and an internal caller required a live ConnectionState. It is an internal guard beneath the public APIs.

Source

Thrown at src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/HubConnection.java:1689

        private ConnectionState state;
        private HubConnectionState hubConnectionState = HubConnectionState.DISCONNECTED;

        public ReconnectingConnectionState(Logger logger) {
            this.logger = logger;
        }

        public void setConnectionState(ConnectionState state) {
            this.lock.lock();
            try {
                this.state = state;
            } finally {
                this.lock.unlock();
            }
        }

        public ConnectionState getConnectionStateUnsynchronized(Boolean allowNull) {
            if (allowNull != true && this.state == null) {
                throw new RuntimeException("Connection is not active.");
            }
            return this.state;
        }

        public ConnectionState getConnectionState() {
            this.lock.lock();
            try {
                if (this.state == null) {
                    throw new RuntimeException("Connection is not active.");
                }
                return this.state;
            } finally {
                this.lock.unlock();
            }
        }

        public HubConnectionState getHubConnectionState() {
            return this.hubConnectionState;

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Ensure the connection is CONNECTED (start() completed, not stopped) before any operation that needs ConnectionState.
  2. Guard public-facing operations with getConnectionState() == CONNECTED checks.
  3. If seen from upload-stream or return-type paths after disconnect, dispose those streams/callbacks on close.

Example fix

// before: accessing connection internals after stop
connection.stop().blockingAwait();
connection.getTransport(); // internal path may hit getConnectionStateUnsynchronized(false) -> throws

// after: only access while connected
if (connection.getConnectionState() == HubConnectionState.CONNECTED) {
    connection.getTransport();
}
Defensive patterns

Strategy: validation

Validate before calling

if (connection.getConnectionState() == HubConnectionState.CONNECTED) {
    // safe to perform operations that require an active ConnectionState
} else {
    // skip or reconnect
}

Type guard

boolean active = connection.getConnectionState() == HubConnectionState.CONNECTED;

Try / catch

// Internal guard; surface via state checks in user code.
try {
    connection.invoke("x").blockingAwait();
} catch (RuntimeException e) {
    if (e.getMessage().equals("Connection is not active.")) {
        // reconnect or defer the operation
    } else { throw e; }
}

Prevention

When it happens

Trigger: An internal code path calls getConnectionStateUnsynchronized(false) after the ConnectionState has been cleared by stopConnection (setConnectionState(null)). For example, code paths in send/invoke/stream/state inspection that require a live connection reach this when the connection was never started or was stopped.

Common situations: Calling internal/derived behavior that touches ConnectionState after stop(). Reconnect logic inspecting state after teardown. Generally surfaces wrapped by higher-level 'not active' checks; seeing this raw message points to an internal caller (e.g. checkUploadStream or getReturnType) running after disconnect.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/8b753241eeb98d56. Report an issue: GitHub.