XTLS/Xray-core · error
empty code
Error message
empty code
What it means
After splitting on ':' and stripping '!' reverse prefixes from the code segment, the code is empty. The rule names a file but no country code, e.g. "ext:geoip.dat:" or "geoip:!".
Source
Thrown at common/geodata/rule_parser.go:72
reverse = !reverse
}
return s, reverse
}
func parseGeoIPRule(rule string, reverse bool) (*IPRule_Geoip, error) {
file, code, ok := strings.Cut(rule, ":")
if !ok {
return nil, errors.New("syntax error")
}
if file == "" {
return nil, errors.New("empty file")
}
code, codeReverse := cutReversePrefix(code)
reverse = reverse != codeReverse
if code == "" {
return nil, errors.New("empty code")
}
code = strings.ToUpper(code)
if err := checkFile(file, code); err != nil {
return nil, err
}
return &IPRule_Geoip{
Geoip: &GeoIPRule{
File: file,
Code: code,
ReverseMatch: reverse,
},
}, nil
}
func parseCustomIPRule(rule string, reverse bool) (*IPRule_Custom, error) {
cidr, err := parseCIDR(rule)View on GitHub (pinned to 7d214f8b09)
Solutions
- Append a valid country code: "geoip:cn", "ext:geoip.dat:us".
- For reverse matching keep the code: "geoip:!cn" (the '!' goes before the code, not instead of it).
Example fix
// before "ip": ["ext:geoip.dat:"] // after "ip": ["ext:geoip.dat:cn"]
Defensive patterns
Strategy: validation
Validate before calling
func validGeoIP(r string) bool {
parts := strings.Split(strings.Trim(r, "!"), ":")
return len(parts) == 2 && parts[0] != "" && strings.Trim(parts[1], "!") != ""
} Prevention
- Treat '!' as a modifier of a non-empty code, never a replacement for it.
When it happens
Trigger: Rule strings "geoip:", "ext:custom.dat:", "geoip:!"; also "geoip:!:cn" is fine but "geoip:!" alone is not.
Common situations: Config typos where the country code was omitted or deleted after the last colon.
Related errors
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/431e09e705198170.
Report an issue: GitHub.