{"record":{"id":"5117687089c62dc7","repo":"XTLS/Xray-core","slug":"invalid-port-range-511768","errorCode":null,"errorMessage":"invalid port range: {}","messagePattern":"invalid port range: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/common.go","lineNumber":209,"sourceCode":"func (v *PortRange) UnmarshalJSON(data []byte) error {\n\tport, err := parseIntPort(data)\n\tif err == nil {\n\t\tv.From = uint32(port)\n\t\tv.To = uint32(port)\n\t\treturn nil\n\t}\n\n\tfrom, to, err := parseJSONStringPort(data)\n\tif err == nil {\n\t\tv.From = uint32(from)\n\t\tv.To = uint32(to)\n\t\tif v.From > v.To || v.To > math.MaxUint16 {\n\t\t\treturn errors.New(\"invalid port range \", v.From, \" -> \", v.To)\n\t\t}\n\t\treturn nil\n\t}\n\n\treturn errors.New(\"invalid port range: \", string(data))\n}\n\ntype PortList struct {\n\tRange []PortRange\n}\n\nfunc (list *PortList) Build() *net.PortList {\n\tportList := new(net.PortList)\n\tfor _, r := range list.Range {\n\t\tportList.Range = append(portList.Range, r.Build())\n\t}\n\treturn portList\n}\n\n// MarshalJSON implements encoding/json.Marshaler.MarshalJSON\nfunc (v *PortList) MarshalJSON() ([]byte, error) {\n\tportStr := v.String()\n\tport, err := strconv.Atoi(portStr)","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/common.go#L191-L227","documentation":"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.","triggerScenarios":"\"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-\".","commonSituations":"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.","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"],"exampleFix":"// before\n\"port\": \"env:HTTPS_PORT\"   // variable unset\n\n// after\nexport HTTPS_PORT=443\n\"port\": \"env:HTTPS_PORT\"","handlingStrategy":"validation","validationCode":"func validatePortJSON(raw []byte) error {\n    var n int\n    if json.Unmarshal(raw, &n) == nil {\n        if n < 1 || n > 65535 {\n            return fmt.Errorf(\"port %d out of range 1-65535\", n)\n        }\n        return nil\n    }\n    var s string\n    if json.Unmarshal(raw, &s) == nil {\n        for _, p := range strings.Split(s, \",\") {\n            if !regexp.MustCompile(`^\\d{1,5}(-\\d{1,5})?$`).MatchString(strings.TrimSpace(p)) {\n                return fmt.Errorf(\"bad port entry %q\", p)\n            }\n        }\n        return nil\n    }\n    return errors.New(\"port must be an integer 1-65535 or a range string\")\n}","typeGuard":null,"tryCatchPattern":"if err := json.Unmarshal(data, &portRange); err != nil {\n    if strings.Contains(err.Error(), \"invalid port range\") {\n        return fmt.Errorf(\"port field %s: use 443 or \\\"1000-2000\\\" or \\\"80,443\\\"\", data)\n    }\n    return err\n}","preventionTips":["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"],"tags":["config","port","validation","env","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}