dotnet/aspnetcore · error · Error

Invalid payload.

Error message

Invalid payload.

What it means

Thrown by _parseMessage when the per-message Uint8Array slice passed in has length 0. Each SignalR MessagePack frame is expected to contain at least a message-type byte; an empty slice means the framing layer handed the parser a zero-length payload.

Solutions

  1. Treat the connection as broken: this indicates protocol corruption; close and reconnect the HubConnection.
  2. Verify the peer is a compliant SignalR MessagePack endpoint.
  3. Filter zero-length subarrays out of test fixtures when fuzzing the parser.

Example fix

// before
// peer sent a frame with declared size 0 → _parseMessage gets []

// after — guard at the framing boundary
for (const m of messages) {
  if (m.length === 0) { logger.log(LogLevel.Warning, 'Skipping zero-length frame'); continue; }
  protocol._parseMessage(m, logger);
}
Defensive patterns

Strategy: validation

Validate before calling

function assertNonEmptyMessage(bytes: Uint8Array) {
  if (bytes.length === 0) throw new Error('Refusing to parse empty MessagePack frame');
}

Type guard

function isNonEmptyFrame(bytes: Uint8Array): boolean { return bytes.length > 0; }

Try / catch

for (const frame of frames) {
  if (frame.length === 0) { logger.log(LogLevel.Warning, 'Skipping empty frame'); continue; }
  try { protocol._parseMessage(frame, logger); } catch (e) { /* connection-level */ }
}

Prevention

When it happens

Trigger: A length-prefix declared a payload of size 0 followed by no body bytes; BinaryMessageFormat.parse returned an empty subarray (rare but possible with prefix size 0); a malformed peer sending zero-length frames.

Common situations: Corrupt or hand-crafted wire data; an upstream framing bug producing zero-length frames; testing with arbitrary byte sequences; a peer exploiting the protocol to send a no-op frame.

Related errors


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

Appendix: source

Thrown at src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts:129

                return this._writeCompletion(message as CompletionMessage);
            case MessageType.Ping:
                return BinaryMessageFormat.write(SERIALIZED_PING_MESSAGE);
            case MessageType.CancelInvocation:
                return this._writeCancelInvocation(message as CancelInvocationMessage);
            case MessageType.Close:
                return this._writeClose();
            case MessageType.Ack:
                return this._writeAck(message as AckMessage);
            case MessageType.Sequence:
                return this._writeSequence(message as SequenceMessage);
            default:
                throw new Error("Invalid message type.");
        }
    }

    private _parseMessage(input: Uint8Array, logger: ILogger): HubMessage | null {
        if (input.length === 0) {
            throw new Error("Invalid payload.");
        }

        const properties = this._decoder.decode(input) as any;
        if (properties.length === 0 || !(properties instanceof Array)) {
            throw new Error("Invalid payload.");
        }

        const messageType = properties[0] as MessageType;

        switch (messageType) {
            case MessageType.Invocation:
                return this._createInvocationMessage(this._readHeaders(properties), properties);
            case MessageType.StreamItem:
                return this._createStreamItemMessage(this._readHeaders(properties), properties);
            case MessageType.Completion:
                return this._createCompletionMessage(this._readHeaders(properties), properties);
            case MessageType.Ping:
                return this._createPingMessage(properties);

View on GitHub (pinned to 3600ca084e)