{"record":{"id":"7e2c5c7aa38c5f1e","repo":"XTLS/Xray-core","slug":"write-minecraft-custom-payload-w","errorCode":null,"errorMessage":"write minecraft custom payload: %w","messagePattern":"write minecraft custom payload: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"transport/internet/finalmask/xmc/packet_stream.go","lineNumber":119,"sourceCode":"\nfunc (s *packetStream) Write(p []byte) (int, error) {\n\tif len(p) == 0 {\n\t\treturn 0, nil\n\t}\n\n\ts.writeMu.Lock()\n\tdefer s.writeMu.Unlock()\n\n\twritten := 0\n\tfor written < len(p) {\n\t\tend := written + maxPacketData\n\t\tif end > len(p) {\n\t\t\tend = len(p)\n\t\t}\n\t\tchannel := String(packetChannel)\n\t\tpayload := RestBytes(p[written:end])\n\t\tif err := writePacket(s.writer, s.localCustomPayloadID(), &channel, &payload); err != nil {\n\t\t\treturn written, fmt.Errorf(\"write minecraft custom payload: %w\", err)\n\t\t}\n\t\twritten = end\n\t}\n\n\treturn written, nil\n}\n\nfunc (s *packetStream) Stop() {\n\ts.stopOnce.Do(func() { close(s.done) })\n}\n\nfunc (s *packetStream) localCustomPayloadID() int {\n\tif s.isClient {\n\t\treturn configurationServerboundCustomPayload\n\t}\n\treturn configurationClientboundCustomPayload\n}\n","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/finalmask/xmc/packet_stream.go#L101-L137","documentation":"packetStream.Write failed while emitting a chunk of the tunnel payload as a Minecraft configuration custom-payload packet on channel \"xmc:data\" (max 24 KiB of data per packet). The wrapped error comes from writePacket and is almost always an underlying write failure on a broken or closed connection.","triggerScenarios":"Calling Write after the peer disconnected; TCP send buffer failure (RST); writing concurrently with a keep-alive after connection teardown; write deadline exceeded.","commonSituations":"Peer or middlebox killed the connection while the proxy was uploading a large burst; application keeps writing after a prior read error marked the conn dead; NAT rebinding blackholes the flow.","solutions":["Check the wrapped error for the real cause (EPIPE, ECONNRESET, timeout)","Stop writing once any Read/Write on the stream has failed — the conn is dead","Re-establish the tunnel at the application level; the stream has no in-stream recovery","Verify payload chunks stay under maxPacketData (the library already splits, so failure is transport-level)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := stream.Write(data); err != nil {\n    conn.Close() // connection is dead; stop writing and reconnect\n    return err\n}","preventionTips":["Fail fast on the first stream error; never continue writing","Propagate errors to the connection manager for reconnection","Monitor for EPIPE bursts to detect middlebox interference with the camouflage stream"],"tags":["go","network","io","minecraft","write"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}