{"record":{"id":"07bf6aa3c782152d","repo":"XTLS/Xray-core","slug":"write-bytes-length-w","errorCode":null,"errorMessage":"write bytes length: %w","messagePattern":"write bytes length: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"transport/internet/finalmask/xmc/protocol.go","lineNumber":357,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"read remaining bytes: %w\", err)\n\t}\n\t*v = append((*v)[:0], buf...)\n\treturn nil\n}\n\nfunc (v *RestBytes) writeTo(w io.Writer) error {\n\tif _, err := w.Write(*v); err != nil {\n\t\treturn fmt.Errorf(\"write remaining bytes: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc (v *Bytes) writeTo(w io.Writer) error {\n\tlength := Varint(len(*v))\n\terr := length.writeTo(w)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write bytes length: %w\", err)\n\t}\n\n\t_, err = w.Write(*v)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write bytes: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc readByte(r io.Reader) (byte, error) {\n\tvar buf [1]byte\n\t_, err := io.ReadFull(r, buf[:])\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"read byte: %w\", err)\n\t}\n\n\treturn buf[0], nil","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/finalmask/xmc/protocol.go#L339-L375","documentation":"Bytes.writeTo first emits the payload length as a Varint; this error wraps a failure of that Varint write. In practice the writer is an in-memory bytes.Buffer during encodePacket, so seeing this escape to a caller means the failure happened on the framed write path (writePacketWithLength's writeFull) or a custom writer, not from bad data.","triggerScenarios":"Encoding a packet with a Bytes field while the connection is closed/stalled; a custom io.Writer passed into the protocol layer returning an error on the first bytes of a field.","commonSituations":"Peer disconnected just before a byte-array field was flushed; write deadline smaller than the time to serialize a large field; test doubles that inject write errors.","solutions":["Check the wrapped error for the real cause; connection-closed means stop writing and tear down.","Keep byte-array fields under the protocol's 1024-byte read cap so peers can parse them.","Buffer the full frame (encodePacket already does) and write once to minimize partial-write windows.","Increase write deadline if the error is a timeout on large frames."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := f.writeTo(w); err != nil {\n    var nerr net.Error\n    if errors.As(err, &nerr) && nerr.Timeout() {\n        w.SetWriteDeadline(time.Now().Add(2 * deadline))\n        return err // caller may retry the whole frame on a fresh conn\n    }\n    return err\n}","preventionTips":["Size write deadlines to the largest frame you send.","Encode into a buffer first (encodePacket) and write once.","Reject/avoid payloads that would push fields past the peer's 1024-byte read cap."],"tags":["go","network","io","protocol-framing"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}