dotnet/aspnetcore · error · Error

Invalid payload for Close message.

Error message

Invalid payload for Close message.

What it means

Thrown by _createCloseMessage when the decoded properties array has fewer than 2 elements. A Close message in the MessagePack protocol is encoded as [MessageType.Close, error?, allowReconnect?] — the type plus at least the error slot. Fewer than 2 elements means the frame is malformed for a Close message.

Solutions

  1. Reconnect: a malformed Close usually means the server is disconnecting anyway; let the HubConnection re-establish.
  2. Verify server and client run compatible SignalR MessagePack protocol versions.
  3. If fuzzing, skip the frame rather than aborting.

Example fix

// before
// close frame encoded as [7] only → throws 'Invalid payload for Close message.'

// after — server must include the error slot (null when none)
// encode as [MessageType.Close, null /*error*/, null /*allowReconnect*/]
Defensive patterns

Strategy: validation

Validate before calling

function isValidCloseProperties(p: unknown[]): boolean {
  return p.length >= 2;
}

Type guard

function isClosePayload(p: unknown[]): p is [number, unknown?, unknown?] {
  return p.length >= 2;
}

Try / catch

try { return protocol.parseMessages(buf, logger); }
catch (e) {
  if (/Invalid payload for Close/.test((e as Error).message)) {
    logger.log(LogLevel.Warning, 'Malformed Close frame — reconnecting');
    await connection.stop(); await connection.start();
  } else throw e;
}

Prevention

When it happens

Trigger: A frame whose MessageType byte was Close (MessageType.Close) but whose decoded array contains only the type byte (no error slot). Produced by a non-compliant server, corrupt bytes that re-typed as Close, or a hand-crafted/fuzzed payload.

Common situations: Fuzzing the MessagePack protocol; a buggy/legacy server emitting a malformed close; protocol version drift where the server's Close encoding differs from the client's expectation.

Related errors


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

Appendix: source

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

            case MessageType.Ping:
                return this._createPingMessage(properties);
            case MessageType.Close:
                return this._createCloseMessage(properties);
            case MessageType.Ack:
                return this._createAckMessage(properties);
            case MessageType.Sequence:
                return this._createSequenceMessage(properties);
            default:
                // Future protocol changes can add message types, old clients can ignore them
                logger.log(LogLevel.Information, "Unknown message type '" + messageType + "' ignored.");
                return null;
        }
    }

    private _createCloseMessage(properties: any[]): HubMessage {
        // check minimum length to allow protocol to add items to the end of objects in future releases
        if (properties.length < 2) {
            throw new Error("Invalid payload for Close message.");
        }

        return {
            // Close messages have no headers.
            allowReconnect: properties.length >= 3 ? properties[2] : undefined,
            error: properties[1],
            type: MessageType.Close,
        } as HubMessage;
    }

    private _createPingMessage(properties: any[]): HubMessage {
        // check minimum length to allow protocol to add items to the end of objects in future releases
        if (properties.length < 1) {
            throw new Error("Invalid payload for Ping message.");
        }

        return {
            // Ping messages have no headers.

View on GitHub (pinned to 3600ca084e)