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

  1. Ensure the server always emits a headers object (empty {} when none) in the correct array position.
  2. Align SignalR versions.
  3. Catch and reconnect — a malformed header field cannot be auto-repaired.
  4. 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

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


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