socketio/socket.io · error · Error
got plaintext data when reconstructing a packet
Error message
got plaintext data when reconstructing a packet
What it means
Thrown by the parser Decoder.add() when a plaintext (string) packet arrives while a BinaryReconstructor is already active. Once a BINARY_EVENT/BINARY_ACK packet has been received, the decoder expects only binary attachments until reconstruction completes; an intervening string frame breaks the stream protocol.
Source
Thrown at packages/socket.io-parser/lib/index.ts:185
{
reviver: undefined,
maxAttachments: 10,
},
typeof opts === "function" ? { reviver: opts } : opts,
);
}
/**
* Decodes an encoded packet string into packet JSON.
*
* @param {String} obj - encoded packet
*/
public add(obj: any) {
let packet;
if (typeof obj === "string") {
if (this.reconstructor) {
throw new Error("got plaintext data when reconstructing a packet");
}
packet = this.decodeString(obj);
const isBinaryEvent = packet.type === PacketType.BINARY_EVENT;
if (isBinaryEvent || packet.type === PacketType.BINARY_ACK) {
packet.type = isBinaryEvent ? PacketType.EVENT : PacketType.ACK;
// binary packet's json
this.reconstructor = new BinaryReconstructor(packet);
} else {
// non-binary full packet
super.emitReserved("decoded", packet);
}
} else if (isBinary(obj) || obj.base64) {
// raw binary data
if (!this.reconstructor) {
throw new Error("got binary data when not reconstructing a packet");
} else {
packet = this.reconstructor.takeBinaryData(obj);
if (packet) {View on GitHub (pinned to ae7fb46e08)
Solutions
- Ensure the transport delivers frames in strict order: the BINARY_EVENT string packet followed by exactly its N binary attachments before any other string packet.
- If using a multiplexed/interleaved source, give each logical packet its own Decoder instance.
- Call decoder.destroy() to reset a stuck reconstructor before feeding fresh data.
Example fix
// before decoder.add(binaryEventString); // stray string arrives mid-reconstruction decoder.add(anotherStringPacket); // throws // after decoder.add(binaryEventString); // wait for all attachments; only then accept new string packets decoder.add(buf1); decoder.add(buf2); // reconstruction done, safe to feed next string packet decoder.add(anotherStringPacket);
Defensive patterns
Strategy: validation
Validate before calling
function canAcceptString(decoder){ return !decoder.reconstructor; } Type guard
function isReconstructing(decoder){ return !!decoder.reconstructor; } Try / catch
try { decoder.add(str); }
catch(e){ if(/plaintext data when reconstructing/.test(e.message)){ decoder.destroy(); decoder.add(str);} else throw e; } Prevention
- Ensure strict frame ordering: BINARY_EVENT header then its attachments.
- Use one Decoder per interleaved logical packet stream.
- Call decoder.destroy() to reset a stuck reconstructor before fresh input.
When it happens
Trigger: The decoder receives a BINARY_EVENT packet (setting up a reconstructor) and then, before all declared attachments have arrived, receives another string-encoded packet via add().
Common situations: A buggy transport multiplexing frames out of order, a proxy/gateway that injects a ping or text frame into the stream, or a custom client that feeds interleaved string and binary data to the same Decoder instance.
Related errors
- got binary data when not reconstructing a packet
- unknown packet type ${p.type}
- Illegal attachments
- unknown event name: ${eventName}
- illegal attachments
AI-assisted analysis of socketio/socket.io@ae7fb46e08 (2026-08-03).
Data as JSON: /data/errors/e958ac69e6b163c4.json.
Report an issue: GitHub.