dotnet/aspnetcore · error
Invalid headers.
Error message
Invalid headers.
What it means
Thrown by _readHeaders when properties[1] (the headers slot) is not of type 'object'. Every header-bearing message (Invocation, StreamItem, Completion) expects its second array element to be a headers object/map (possibly empty {}). This fires when that slot is a string, number, boolean, null, or undefined — i.e. a malformed header field.
Source
Thrown at src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts:368
return BinaryMessageFormat.write(payload.slice());
}
private _writeAck(ackMessage: AckMessage): ArrayBuffer {
const payload = this._encoder.encode([MessageType.Ack, ackMessage.sequenceId]);
return BinaryMessageFormat.write(payload.slice());
}
private _writeSequence(sequenceMessage: SequenceMessage): ArrayBuffer {
const payload = this._encoder.encode([MessageType.Sequence, sequenceMessage.sequenceId]);
return BinaryMessageFormat.write(payload.slice());
}
private _readHeaders(properties: any): MessageHeaders {
const headers: MessageHeaders = properties[1] as MessageHeaders;
if (typeof headers !== "object") {
throw new Error("Invalid headers.");
}
return headers;
}
}
View on GitHub (pinned to 294cab2f9b)
Solutions
- Ensure the server always emits a headers object (empty {} when none) in the correct array position.
- Align SignalR versions.
- Catch and reconnect — a malformed header field cannot be auto-repaired.
- Inspect server-side code that populates HubMessage.Headers.
Example fix
// before // server: msg.Headers = "x" // wrong type // after // server: msg.Headers = new Dictionary<string, string>(); // object/map
Defensive patterns
Strategy: validation
Validate before calling
// if you decode frames yourself, validate the headers slot is an object
function headersAreValid(decoded: unknown): boolean {
return Array.isArray(decoded)
&& decoded.length >= 2
&& typeof decoded[1] === 'object'
&& decoded[1] !== null;
} Type guard
function isMessageHeaders(v: unknown): v is Record<string, string> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Try / catch
try {
const messages = protocol.parseMessages(buffer, logger);
} catch (e) {
if (e.message === 'Invalid headers.') {
logger.log(LogLevel.Error, 'Message headers field is not an object; reconnecting.');
await connection.start();
} else throw e;
} Prevention
- Ensure the server always emits a headers object (empty {} when none) in the correct array position.
- Align SignalR versions so the headers slot is consistently positioned.
- Catch header-validation failures and reconnect rather than crashing.
When it happens
Trigger: Server serializes a message with headers set to null or a string instead of an object; a frame where the headers map was omitted shifting elements; typeof null === 'object' passes, but a string/number headers value triggers it.
Common situations: Custom server not emitting the headers map; version mismatch; corruption; a hub method that sets invalid headers via the IHubContext.
Related errors
- Invalid message type.
- Invalid payload for Close message.
- Invalid payload for Ping message.
- Invalid payload for Invocation message.
- Invalid payload for StreamItem message.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/4c3b54fe68806e78.
Report an issue: GitHub.