dotnet/aspnetcore · 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 valid Close message is encoded as [MessageType.Close, error?, allowReconnect?] so it needs at least the type and the (possibly null) error slot. The minimum-length check lets the protocol add trailing fields in future versions without breaking.

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 294cab2f9b)

Solutions

  1. Verify the server is a supported ASP.NET Core SignalR server emitting the documented Close frame shape.
  2. Align client/server SignalR versions.
  3. If you control the sender, ensure Close is encoded as [MessageType.Close, error] (at least 2 elements).
  4. Wrap parseMessages in try/catch and trigger reconnection logic since a Close frame parse failure usually precedes disconnect anyway.

Example fix

// before
const [_, resp] = handshake; // close arrives, parseMessages throws

// after
try {
  const messages = protocol.parseMessages(buffer, logger);
} catch (e) {
  if (/Close message/.test(e.message)) {
    logger.log(LogLevel.Warning, 'Malformed Close frame; closing connection.');
  }
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const messages = protocol.parseMessages(buffer, logger);
} catch (e) {
  if (/Close message/.test(e.message)) {
    logger.log(LogLevel.Warning, 'Malformed Close frame; treating connection as closed.');
    await connection.stop();
  } else throw e;
}

Prevention

When it happens

Trigger: A Close frame encoded as a single-element array [MessageType.Close] (missing the error field); a malformed server-side Close serialization.

Common situations: Server and client protocol version mismatch where an older server omits the error slot; a custom server implementation building Close frames by hand; corrupted frame that lost trailing elements.

Related errors


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