{"record":{"id":"c2c923834fbc72d6","repo":"XTLS/Xray-core","slug":"failed-to-marshal-addons-protobuf-value","errorCode":null,"errorMessage":"failed to marshal addons protobuf value","messagePattern":"failed to marshal addons protobuf value","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"proxy/vless/encoding/addons.go","lineNumber":22,"sourceCode":"\t\"context\"\n\t\"io\"\n\t\"net\"\n\n\t\"github.com/xtls/xray-core/common/buf\"\n\t\"github.com/xtls/xray-core/common/errors\"\n\t\"github.com/xtls/xray-core/common/protocol\"\n\t\"github.com/xtls/xray-core/common/session\"\n\t\"github.com/xtls/xray-core/proxy\"\n\t\"github.com/xtls/xray-core/proxy/vless\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\nfunc EncodeHeaderAddons(buffer *buf.Buffer, addons *Addons) error {\n\tswitch addons.Flow {\n\tcase vless.XRV:\n\t\tbytes, err := proto.Marshal(addons)\n\t\tif err != nil {\n\t\t\treturn errors.New(\"failed to marshal addons protobuf value\").Base(err)\n\t\t}\n\t\tif err := buffer.WriteByte(byte(len(bytes))); err != nil {\n\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)","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/vless/encoding/addons.go#L4-L40","documentation":"When encoding a VLESS request header for the XTLS Vision flow (addons.Flow == vless.XRV), the Addons protobuf message is serialized with proto.Marshal. Marshaling an in-memory message essentially cannot fail for this schema (no required fields, no unknown overflow), so this error is a defensive internal invariant rather than an expected runtime condition.","triggerScenarios":"Theoretically: a corrupted Addons message state or a protobuf runtime incompatibility after an upgrade mixing old/new builds on the wire path. In practice, users should not see it.","commonSituations":"Mixed xray versions or a fork with a modified addons.proto writing incompatible field numbers; memory corruption in a buggy fork.","solutions":["If observed, upgrade both ends to matching official xray-core versions","Report the full log line with versions to xray-core maintainers","As a workaround, switch the flow off (remove \"flow\": \"xtls-rprx-vision\") to bypass addons encoding"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := encoding.EncodeHeaderAddons(buffer, addons); err != nil {\n\tif strings.Contains(err.Error(), \"failed to marshal addons\") {\n\t\t// internal invariant: log and drop the connection, do not retry\n\t\tlog.Warnf(\"addons marshal failed: %v\", err)\n\t\treturn conn.Close()\n\t}\n\treturn err\n}","preventionTips":["Keep both endpoints on matching official xray-core versions","Do not fork addons.proto with incompatible field changes"],"tags":["vless","xtls","protobuf","encoding","internal"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}