XTLS/Xray-core · error
invalid port range: {}
Error message
invalid port range: {} What it means
Thrown by PortRange.UnmarshalJSON in infra/conf/common.go as the final fallback when the JSON value for a port field is neither a valid integer (parseIntPort failed) nor a parseable string port/range (parseJSONStringPort failed). The raw JSON data is appended to the message so you can see the offending value.
Source
Thrown at infra/conf/common.go:209
func (v *PortRange) UnmarshalJSON(data []byte) error {
port, err := parseIntPort(data)
if err == nil {
v.From = uint32(port)
v.To = uint32(port)
return nil
}
from, to, err := parseJSONStringPort(data)
if err == nil {
v.From = uint32(from)
v.To = uint32(to)
if v.From > v.To || v.To > math.MaxUint16 {
return errors.New("invalid port range ", v.From, " -> ", v.To)
}
return nil
}
return errors.New("invalid port range: ", string(data))
}
type PortList struct {
Range []PortRange
}
func (list *PortList) Build() *net.PortList {
portList := new(net.PortList)
for _, r := range list.Range {
portList.Range = append(portList.Range, r.Build())
}
return portList
}
// MarshalJSON implements encoding/json.Marshaler.MarshalJSON
func (v *PortList) MarshalJSON() ([]byte, error) {
portStr := v.String()
port, err := strconv.Atoi(portStr)View on GitHub (pinned to 7d214f8b09)
Solutions
- Set port to an integer 1-65535: "port": 443
- Or a valid range string: "port": "1000-2000"
- For env: ports ensure the variable is set and numeric before starting Xray
- Read the appended raw data in the message to find which value failed
Example fix
// before "port": "env:HTTPS_PORT" // variable unset // after export HTTPS_PORT=443 "port": "env:HTTPS_PORT"
Defensive patterns
Strategy: validation
Validate before calling
func validatePortJSON(raw []byte) error {
var n int
if json.Unmarshal(raw, &n) == nil {
if n < 1 || n > 65535 {
return fmt.Errorf("port %d out of range 1-65535", n)
}
return nil
}
var s string
if json.Unmarshal(raw, &s) == nil {
for _, p := range strings.Split(s, ",") {
if !regexp.MustCompile(`^\d{1,5}(-\d{1,5})?$`).MatchString(strings.TrimSpace(p)) {
return fmt.Errorf("bad port entry %q", p)
}
}
return nil
}
return errors.New("port must be an integer 1-65535 or a range string")
} Try / catch
if err := json.Unmarshal(data, &portRange); err != nil {
if strings.Contains(err.Error(), "invalid port range") {
return fmt.Errorf("port field %s: use 443 or \"1000-2000\" or \"80,443\"", data)
}
return err
} Prevention
- Never use port 0 or names; only integers 1-65535
- Verify env: port variables are exported and numeric
- Use xray's config test mode before restart
When it happens
Trigger: "port": "abc", "port": -1, "port": 0 (PortFromInt rejects 0), "port": true, "port": [443], or "port": null. Also strings containing '-' whose halves are not numbers, like "443-".
Common situations: Unquoted numeric strings that contain spaces; using a protocol name instead of a port; referencing an env variable ("port": "env:PORT") that is unset — it resolves to empty string and parsing fails.
Related errors
- invalid port range:
- invalid port range {} -> {}
- invalid port: {}
- invalid portMap: {}
- invalid redirect port: {}
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/5117687089c62dc7.
Report an issue: GitHub.