XTLS/Xray-core · error
VLESS fallbacks: invalid PROXY protocol version, "xver" only
Error message
VLESS fallbacks: invalid PROXY protocol version, "xver" only accepts 0, 1, 2
What it means
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.
Source
Thrown at infra/conf/vless.go:210
if strings.HasPrefix(fb.Dest, "@@") && (runtime.GOOS == "linux" || runtime.GOOS == "android") {
fullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) // may need padding to work with haproxy
copy(fullAddr, fb.Dest[1:])
fb.Dest = string(fullAddr)
}
} else {
if _, err := strconv.Atoi(fb.Dest); err == nil {
fb.Dest = "localhost:" + fb.Dest
}
if _, _, err := net.SplitHostPort(fb.Dest); err == nil {
fb.Type = "tcp"
}
}
}
if fb.Type == "" {
return nil, errors.New(`VLESS fallbacks: please fill in a valid value for every "dest"`)
}
if fb.Xver > 2 {
return nil, errors.New(`VLESS fallbacks: invalid PROXY protocol version, "xver" only accepts 0, 1, 2`)
}
}
return config, nil
}
type VLessReverseConfig struct {
Tag string `json:"tag"`
Sniffing *SniffingConfig `json:"sniffing"`
}
func (c *VLessReverseConfig) Build() (*vless.Reverse, error) {
if c.Tag == "" {
return nil, errors.New(`VLESS reverse: "tag" can't be empty`)
}
r := &vless.Reverse{
Tag: c.Tag,
}View on GitHub (pinned to 7d214f8b09)
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
Example fix
// before
"fallbacks": [{ "dest": 80, "xver": 3 }]
// after
"fallbacks": [{ "dest": 80, "xver": 1 }] Defensive patterns
Strategy: validation
Validate before calling
func validateXver(fb map[string]any) error {
if v, ok := fb["xver"]; ok {
n, ok := v.(float64)
if !ok || n != math.Trunc(n) || n < 0 || n > 2 {
return fmt.Errorf("xver must be integer 0, 1, or 2, got %v", v)
}
}
return nil
} Type guard
func validXver(v any) bool {
n, ok := v.(float64)
return ok && n == math.Trunc(n) && n >= 0 && n <= 2
} Prevention
- 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
When it happens
Trigger: "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+.
Common situations: 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.
Related errors
- VLESS fallbacks: "path" must be empty or start with "/"
- VLESS fallbacks: please fill in a valid value for every "des
- VLESS reverse: "tag" can't be empty
- VLESS reverse: invalid "sniffing" config
- VLESS settings: "vnext" should have one and only one member.
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/4b39cb0e5b8aa285.
Report an issue: GitHub.