dotnet/aspnetcore · error · Error

Invalid headers.

Error message

Invalid headers.

What it means

Thrown by the MessagePack protocol decoder when reading headers from an incoming message's properties array. The headers are expected at index [1] of the decoded properties and must be a plain object. If that slot is anything other than an object (e.g. undefined, a number, a string, or an array), the client cannot associate headers with the message and refuses to process it.

Solutions

  1. Align client and server @microsoft/signalr-protocol-msgpack versions to the same major release as the server package.
  2. Verify the endpoint URL actually points to a SignalR MessagePack hub, not a JSON hub or unrelated service.
  3. Inspect the raw bytes being delivered to parseMessages to confirm the properties array shape matches the documented MessagePack framing.
  4. If interoperating with a non-.NET server, ensure the encoder produces the exact properties layout: [headers, ...] where headers is a Map/object.

Example fix

// before: mismatched protocol packages
// server: Microsoft.AspNetCore.SignalR.Common 3.1
// client: @microsoft/signalr-protocol-msgpack 5.0

// after: aligned versions
// server: Microsoft.AspNetCore.SignalR.Common 5.0
// client: @microsoft/signalr-protocol-msgpack 5.0
Defensive patterns

Strategy: validation

Validate before calling

// Validate that your MessagePack encoder produces an object at properties[1]
function assertValidHeaders(properties: unknown): asserts properties is [unknown, Record<string, unknown>] {
  if (!Array.isArray(properties) || typeof properties[1] !== "object" || properties[1] === null) {
    throw new Error("Refusing to send: MessagePack headers are malformed.");
  }
}

Type guard

function isMessageHeaders(v: unknown): v is Record<string, string> {
  return typeof v === "object" && v !== null && !Array.isArray(v);
}

Try / catch

try {
  await connection.start();
} catch (e) {
  if (e instanceof Error && e.message === "Invalid headers.") {
    // almost always a client/server protocol version mismatch
    console.error("MessagePack protocol mismatch — align @microsoft/signalr-protocol-msgpack with the server version.");
  }
  throw e;
}

Prevention

When it happens

Trigger: Invoked from _readHeaders(properties) when a MessagePack-encoded HubMessage is parsed and properties[1] fails the typeof === "object" check. Happens when a client/server version mismatch alters the encoded properties layout, when a custom MessagePack encoder omits the headers map, or when a non-SignalR endpoint returns bytes that get fed into the MessagePack protocol parser.

Common situations: Server and client are running incompatible MessagePack protocol versions (e.g. ASP.NET Core SignalR 1.x vs 3.x changed the properties layout). A proxy or middleware rewrote or truncated the binary frame. Connecting a MessagePack client to a server that only speaks JSON.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/4c3b54fe68806e78. Report an issue: GitHub.

Appendix: 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 3600ca084e)