{"record":{"id":"e7a004bd939ef754","repo":"dotnet/aspnetcore","slug":"invalid-payload","errorCode":null,"errorMessage":"Invalid payload.","messagePattern":"Invalid payload\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts","lineNumber":129,"sourceCode":"                return this._writeCompletion(message as CompletionMessage);\n            case MessageType.Ping:\n                return BinaryMessageFormat.write(SERIALIZED_PING_MESSAGE);\n            case MessageType.CancelInvocation:\n                return this._writeCancelInvocation(message as CancelInvocationMessage);\n            case MessageType.Close:\n                return this._writeClose();\n            case MessageType.Ack:\n                return this._writeAck(message as AckMessage);\n            case MessageType.Sequence:\n                return this._writeSequence(message as SequenceMessage);\n            default:\n                throw new Error(\"Invalid message type.\");\n        }\n    }\n\n    private _parseMessage(input: Uint8Array, logger: ILogger): HubMessage | null {\n        if (input.length === 0) {\n            throw new Error(\"Invalid payload.\");\n        }\n\n        const properties = this._decoder.decode(input) as any;\n        if (properties.length === 0 || !(properties instanceof Array)) {\n            throw new Error(\"Invalid payload.\");\n        }\n\n        const messageType = properties[0] as MessageType;\n\n        switch (messageType) {\n            case MessageType.Invocation:\n                return this._createInvocationMessage(this._readHeaders(properties), properties);\n            case MessageType.StreamItem:\n                return this._createStreamItemMessage(this._readHeaders(properties), properties);\n            case MessageType.Completion:\n                return this._createCompletionMessage(this._readHeaders(properties), properties);\n            case MessageType.Ping:\n                return this._createPingMessage(properties);","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts#L111-L147","documentation":"Thrown in _parseMessage when an individual frame extracted by BinaryMessageFormat.parse has length 0. BinaryMessageFormat already split the buffer on varint length prefixes, so a zero-length frame means the wire data was structurally broken (a length prefix pointed at an empty payload). This is a defense against feeding garbage to the msgpack decoder.","triggerScenarios":"Corrupt or truncated binary frame where a varint length prefix is followed by zero bytes; a man-in-the-middle or proxy that strips payload bytes; manually constructing a buffer with a 0x00 length prefix then data.","commonSituations":"Network interruption mid-frame leaving a partial buffer that the length prefix claims is empty; a bug in a custom transport that pre-slices frames incorrectly; version skew where an old server emits a frame shape the client cannot interpret.","solutions":["Capture the raw bytes at the transport layer and verify the varint length prefixes are consistent with the available bytes before parsing.","Check the SignalR server and client protocol versions match (both should support MessagePack v2).","Inspect the connection for middleware/proxies that may alter the binary stream (e.g. a text-mode reverse proxy).","Add a try/catch around the connection's onreceive handler to log the offending buffer length and reconnect."],"exampleFix":"// before\nconst hubMessages = protocol.parseMessages(rawBuffer, logger);\n\n// after\ntry {\n  const hubMessages = protocol.parseMessages(rawBuffer, logger);\n} catch (e) {\n  logger.log(LogLevel.Error, 'Corrupt msgpack frame, reconnecting: ' + e.message);\n  await connection.stop();\n  await connection.start();\n}","handlingStrategy":"try-catch","validationCode":"// validate varint length prefixes before parsing\nfunction framesLookComplete(buffer: ArrayBuffer): boolean {\n  const u = new Uint8Array(buffer);\n  for (let i = 0; i < u.length;) {\n    let len = 0, shift = 0, n = 0, b;\n    do { b = u[i + n]; len |= (b & 0x7f) << shift; shift += 7; n++; }\n    while (n < 5 && (b & 0x80) !== 0);\n    if (len === 0) return false; // a zero-length frame will trigger error 102\n    i += n + len;\n    if (i > u.length) return false;\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  const msgs = protocol.parseMessages(buffer, logger);\n} catch (e) {\n  if (e.message === 'Invalid payload.') {\n    logger.log(LogLevel.Error, 'Zero-length msgpack frame; reconnecting.');\n    await connection.start();\n    return;\n  }\n  throw e;\n}","preventionTips":["Treat any zero-length frame as unrecoverable corruption and reconnect.","Do not share the ArrayBuffer being parsed with code that writes to it concurrently.","Log the raw buffer length at the transport boundary to spot truncation."],"tags":["messagepack","binary-protocol","corruption","parsing","network"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}