dotnet/aspnetcore · error · Error
negotiateResponse.error
Error message
negotiateResponse.error
What it means
If the /negotiate response body contains an 'error' field, the server is reporting a negotiation failure (e.g. hub not found, protocol unsupported, transport disabled). The client surfaces that server-provided string by throwing new Error(negotiateResponse.error).
Source
Thrown at src/SignalR/clients/ts/signalr/src/HttpConnection.ts:276
// We should just call connect directly in this case.
// No fallback or negotiate in this case.
await this._startTransport(url, transferFormat);
} else {
throw new Error("Negotiation can only be skipped when using the WebSocket transport directly.");
}
} else {
let negotiateResponse: INegotiateResponse | null = null;
let redirects = 0;
do {
negotiateResponse = await this._getNegotiationResponse(url);
// the user tries to stop the connection when it is being started
if (this._connectionState === ConnectionState.Disconnecting || this._connectionState === ConnectionState.Disconnected) {
throw new AbortError("The connection was stopped during negotiation.");
}
if (negotiateResponse.error) {
throw new Error(negotiateResponse.error);
}
if ((negotiateResponse as any).ProtocolVersion) {
throw new Error("Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.");
}
if (negotiateResponse.url) {
url = negotiateResponse.url;
}
if (negotiateResponse.accessToken) {
// Replace the current access token factory with one that uses
// the returned access token
this._setTransportAccessToken(negotiateResponse.accessToken);
}
redirects++;
}View on GitHub (pinned to 3600ca084e)
Solutions
- Read the actual error string — it is the server's explanation (e.g. 'The Server was unable to negotiate...').
- Verify the hub is registered at the exact route (case-sensitive) the client is hitting.
- Confirm at least one transport the client allows is enabled on the server (ConfigureKestrel/AddSignalR options).
- For Azure SignalR, check the connection string and that the endpoint is reachable.
Example fix
// before
try { await connection.start(); }
catch (e) { console.error(e); }
// after — surface the server error verbosely
try { await connection.start(); }
catch (e) {
if (typeof e.message === "string" && e.message.length)
console.error("Negotiate error from server:", e.message);
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: hit negotiate and surface the server's error
async function probeNegotiate(url: string) {
const r = await fetch(`${url}/negotiate?negotiateVersion=1`, { method: "POST" });
const body = await r.json();
if (body.error) throw new Error(`Server negotiate error: ${body.error}`);
return body;
} Type guard
function hasNegotiateError(v: unknown): v is { error: string } {
return typeof v === "object" && v !== null && typeof (v as any).error === "string";
} Try / catch
try { await connection.start(); }
catch (e) {
const msg = (e instanceof Error && e.message) || "";
// The message IS the server-provided error string; log it for diagnosis
console.error("Server returned negotiate error:", msg);
throw e;
} Prevention
- Run a /negotiate probe in CI to catch hub-route/transport misconfig early.
- Always log the raw error message — it is the server's explanation.
- Confirm at least one client-allowed transport is enabled server-side.
When it happens
Trigger: Any 200 negotiate response whose JSON contains an error string. The server's NegotiateMiddleware or hub endpoint wrote an error: "..." into the response. Causes include unknown hub, disallowed transport, invalid protocol, or a custom IConnection that rejects negotiation.
Common situations: Hub route typo (negotiate returns error indicating no hub). Server config disables all transports the client requested. Azure SignalR Service misconfigured (wrong endpoint/key yields an error in negotiate). ConnectionId could not be generated.
Related errors
- Negotiation can only be skipped when using the WebSocket tra
- 'WebSocket' is not supported in your environment.
- 'EventSource' is not supported in your environment.
- Unknown transport: ${transport}.
- Negotiation can only be skipped when using the WebSocket tra
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/856d2a7df26e31e5.
Report an issue: GitHub.