{"record":{"id":"4b39cb0e5b8aa285","repo":"XTLS/Xray-core","slug":"vless-fallbacks-invalid-proxy-protocol-version","errorCode":null,"errorMessage":"VLESS fallbacks: invalid PROXY protocol version, \"xver\" only accepts 0, 1, 2","messagePattern":"VLESS fallbacks: invalid PROXY protocol version, \"xver\" only accepts 0, 1, 2","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/vless.go","lineNumber":210,"sourceCode":"\t\t\t\tif strings.HasPrefix(fb.Dest, \"@@\") && (runtime.GOOS == \"linux\" || runtime.GOOS == \"android\") {\n\t\t\t\t\tfullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) // may need padding to work with haproxy\n\t\t\t\t\tcopy(fullAddr, fb.Dest[1:])\n\t\t\t\t\tfb.Dest = string(fullAddr)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif _, err := strconv.Atoi(fb.Dest); err == nil {\n\t\t\t\t\tfb.Dest = \"localhost:\" + fb.Dest\n\t\t\t\t}\n\t\t\t\tif _, _, err := net.SplitHostPort(fb.Dest); err == nil {\n\t\t\t\t\tfb.Type = \"tcp\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif fb.Type == \"\" {\n\t\t\treturn nil, errors.New(`VLESS fallbacks: please fill in a valid value for every \"dest\"`)\n\t\t}\n\t\tif fb.Xver > 2 {\n\t\t\treturn nil, errors.New(`VLESS fallbacks: invalid PROXY protocol version, \"xver\" only accepts 0, 1, 2`)\n\t\t}\n\t}\n\n\treturn config, nil\n}\n\ntype VLessReverseConfig struct {\n\tTag      string          `json:\"tag\"`\n\tSniffing *SniffingConfig `json:\"sniffing\"`\n}\n\nfunc (c *VLessReverseConfig) Build() (*vless.Reverse, error) {\n\tif c.Tag == \"\" {\n\t\treturn nil, errors.New(`VLESS reverse: \"tag\" can't be empty`)\n\t}\n\tr := &vless.Reverse{\n\t\tTag: c.Tag,\n\t}","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/vless.go#L192-L228","documentation":"Thrown by VLessInboundConfig.Build() when a fallback's \"xver\" (PROXY protocol version) is greater than 2. Only 0 (disable), 1 (PROXY v1, text) and 2 (PROXY v2, binary) exist; any larger integer is meaningless and rejected. Note that negative values cannot occur because the field is an unsigned integer type.","triggerScenarios":"\"fallbacks\":[{\"dest\":80,\"xver\":3}] or any xver > 2; typically from guessing that higher means newer/better, or from configs edited for a different proxy that supports xver 3+.","commonSituations":"Users copy xver from HAProxy docs (which discusses v2) and bump it; automated config generators emitting a default of 3; hand-edited JSON after an upgrade.","solutions":["Set \"xver\" to 0, 1, or 2 — 1 or 2 if the fallback target understands PROXY protocol","Set \"xver\": 0 if the backend (e.g. plain nginx without proxy_protocol) does not support it"],"exampleFix":"// before\n\"fallbacks\": [{ \"dest\": 80, \"xver\": 3 }]\n// after\n\"fallbacks\": [{ \"dest\": 80, \"xver\": 1 }]","handlingStrategy":"validation","validationCode":"func validateXver(fb map[string]any) error {\n\tif v, ok := fb[\"xver\"]; ok {\n\t\tn, ok := v.(float64)\n\t\tif !ok || n != math.Trunc(n) || n < 0 || n > 2 {\n\t\t\treturn fmt.Errorf(\"xver must be integer 0, 1, or 2, got %v\", v)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func validXver(v any) bool {\n\tn, ok := v.(float64)\n\treturn ok && n == math.Trunc(n) && n >= 0 && n <= 2\n}","tryCatchPattern":null,"preventionTips":["Remember PROXY protocol has only versions 1 and 2 (0 disables)","Enable xver only when the fallback target is configured to accept proxy_protocol","Use 0 for plain HTTP backends like a default nginx"],"tags":["vless","config","fallbacks","proxy-protocol","validation","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}