{"record":{"id":"6fed53e730a030f7","repo":"XTLS/Xray-core","slug":"failed-to-read-addons-protobuf-length","errorCode":null,"errorMessage":"failed to read addons protobuf length","messagePattern":"failed to read addons protobuf length","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"proxy/vless/encoding/addons.go","lineNumber":43,"sourceCode":"\t\t\treturn errors.New(\"failed to write addons protobuf length\").Base(err)\n\t\t}\n\t\tif _, err := buffer.Write(bytes); err != nil {\n\t\t\treturn errors.New(\"failed to write addons protobuf value\").Base(err)\n\t\t}\n\tdefault:\n\t\tif err := buffer.WriteByte(0); err != nil {\n\t\t\treturn errors.New(\"failed to write addons protobuf length\").Base(err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc DecodeHeaderAddons(buffer *buf.Buffer, reader io.Reader) (*Addons, error) {\n\taddons := new(Addons)\n\tbuffer.Clear()\n\tif _, err := buffer.ReadFullFrom(reader, 1); err != nil {\n\t\treturn nil, errors.New(\"failed to read addons protobuf length\").Base(err)\n\t}\n\n\tif length := int32(buffer.Byte(0)); length != 0 {\n\t\tbuffer.Clear()\n\t\tif _, err := buffer.ReadFullFrom(reader, length); err != nil {\n\t\t\treturn nil, errors.New(\"failed to read addons protobuf value\").Base(err)\n\t\t}\n\n\t\tif err := proto.Unmarshal(buffer.Bytes(), addons); err != nil {\n\t\t\treturn nil, errors.New(\"failed to unmarshal addons protobuf value\").Base(err)\n\t\t}\n\n\t\t// Verification.\n\t\tswitch addons.Flow {\n\t\tdefault:\n\t\t}\n\t}\n","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/vless/encoding/addons.go#L25-L61","documentation":"On the server side, decoding a VLESS request header first reads one byte of addons length from the connection. ReadFullFrom on the network reader fails when the connection provides zero bytes (EOF) or is reset/times out before the byte arrives. This usually means the client disconnected during handshake or is not a compatible VLESS client.","triggerScenarios":"Client closes the connection right after TCP connect (port scanners, health probes like CDN/load-balancer TCP checks); TLS clients hitting a non-TLS VLESS port; middleboxes resetting connections; client xray version mismatched so the framing diverges.","commonSituations":"Exposing a VLESS inbound to the public internet (scanners constantly probe); misdirected traffic (https to the VLESS port); GFW/network interference; reverse proxy TCP health checks.","solutions":["Confirm the client targets the right port/protocol and both ends run compatible xray versions","Put VLESS behind a TLS/REALITY layer or use port hopping/reverse proxy health checks that send data","If caused by scanners, it is safe to log-and-ignore; the per-connection handshake fails cleanly","Check MTU/timeout settings if legitimate clients hit it mid-handshake"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"addons, err := encoding.DecodeHeaderAddons(buffer, reader)\nif err != nil {\n\tif errors.Is(err, io.EOF) || strings.Contains(err.Error(), \"failed to read addons protobuf length\") {\n\t\t// peer disconnected mid-handshake (scanner/reset): log at debug, close\n\t\treturn conn.Close()\n\t}\n\treturn err\n}","preventionTips":["Expect scanners on public VLESS ports; log handshake EOFs at debug level","Ensure clients target the correct port/protocol and matching xray version","Use REALITY/TLS so non-VLESS probes fail earlier and cleanly"],"tags":["vless","server","handshake","network","eof"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}