{"record":{"id":"751865e8193be280","repo":"dotnet/aspnetcore","slug":"invalid-payload-for-close-message","errorCode":null,"errorMessage":"Invalid payload for Close message.","messagePattern":"Invalid payload for Close message\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts","lineNumber":164,"sourceCode":"            case MessageType.Ping:\n                return this._createPingMessage(properties);\n            case MessageType.Close:\n                return this._createCloseMessage(properties);\n            case MessageType.Ack:\n                return this._createAckMessage(properties);\n            case MessageType.Sequence:\n                return this._createSequenceMessage(properties);\n            default:\n                // Future protocol changes can add message types, old clients can ignore them\n                logger.log(LogLevel.Information, \"Unknown message type '\" + messageType + \"' ignored.\");\n                return null;\n        }\n    }\n\n    private _createCloseMessage(properties: any[]): HubMessage {\n        // check minimum length to allow protocol to add items to the end of objects in future releases\n        if (properties.length < 2) {\n            throw new Error(\"Invalid payload for Close message.\");\n        }\n\n        return {\n            // Close messages have no headers.\n            allowReconnect: properties.length >= 3 ? properties[2] : undefined,\n            error: properties[1],\n            type: MessageType.Close,\n        } as HubMessage;\n    }\n\n    private _createPingMessage(properties: any[]): HubMessage {\n        // check minimum length to allow protocol to add items to the end of objects in future releases\n        if (properties.length < 1) {\n            throw new Error(\"Invalid payload for Ping message.\");\n        }\n\n        return {\n            // Ping messages have no headers.","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts#L146-L182","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Reconnect: a malformed Close usually means the server is disconnecting anyway; let the HubConnection re-establish.","Verify server and client run compatible SignalR MessagePack protocol versions.","If fuzzing, skip the frame rather than aborting."],"exampleFix":"// before\n// close frame encoded as [7] only → throws 'Invalid payload for Close message.'\n\n// after — server must include the error slot (null when none)\n// encode as [MessageType.Close, null /*error*/, null /*allowReconnect*/]","handlingStrategy":"validation","validationCode":"function isValidCloseProperties(p: unknown[]): boolean {\n  return p.length >= 2;\n}","typeGuard":"function isClosePayload(p: unknown[]): p is [number, unknown?, unknown?] {\n  return p.length >= 2;\n}","tryCatchPattern":"try { return protocol.parseMessages(buf, logger); }\ncatch (e) {\n  if (/Invalid payload for Close/.test((e as Error).message)) {\n    logger.log(LogLevel.Warning, 'Malformed Close frame — reconnecting');\n    await connection.stop(); await connection.start();\n  } else throw e;\n}","preventionTips":["Use the official SignalR server, which always emits well-formed Close frames.","Keep client and server protocol versions aligned.","Reconnect on Close-frame corruption rather than retrying the parse."],"tags":["signalr","messagepack","close-message","validation","wire-format"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}