{"record":{"id":"a714db3493986d1d","repo":"MHSanaei/3x-ui","slug":"parse-xui-port-w","errorCode":null,"errorMessage":"parse XUI_PORT: %w","messagePattern":"parse XUI_PORT: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/config.go","lineNumber":120,"sourceCode":"// IsDebug returns true if debug mode is enabled via the XUI_DEBUG environment variable.\nfunc IsDebug() bool {\n\treturn os.Getenv(\"XUI_DEBUG\") == \"true\"\n}\n\n// IsSkipHSTS returns true if skipping HSTS mode is enabled via the XUI_SKIP_HSTS environment variable.\nfunc IsSkipHSTS() bool {\n\treturn os.Getenv(\"XUI_SKIP_HSTS\") == \"true\"\n}\n\nfunc GetPortOverride() (port int, configured bool, err error) {\n\tvalue, ok := os.LookupEnv(\"XUI_PORT\")\n\tif !ok || strings.TrimSpace(value) == \"\" {\n\t\treturn 0, false, nil\n\t}\n\n\tport, err = strconv.Atoi(strings.TrimSpace(value))\n\tif err != nil {\n\t\treturn 0, true, fmt.Errorf(\"parse XUI_PORT: %w\", err)\n\t}\n\tif port < 1 || port > 65535 {\n\t\treturn 0, true, fmt.Errorf(\"XUI_PORT must be between 1 and 65535\")\n\t}\n\n\treturn port, true, nil\n}\n\n// GetBinFolderPath returns the path to the binary folder, defaulting to \"bin\" if not set via XUI_BIN_FOLDER.\nfunc GetBinFolderPath() string {\n\tbinFolderPath := os.Getenv(\"XUI_BIN_FOLDER\")\n\tif binFolderPath == \"\" {\n\t\tbinFolderPath = \"bin\"\n\t}\n\treturn binFolderPath\n}\n\nfunc getBaseDir() string {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/config/config.go#L102-L138","documentation":"GetPortOverride reads XUI_PORT, and after trimming whitespace hands it to strconv.Atoi; any non-integer text produces this wrapped error. It only fires when the env var is set to a non-empty non-numeric value — unset or empty returns (0, false, nil). Callers use it to override the DB-stored web port, so a bad value aborts effective port resolution.","triggerScenarios":"XUI_PORT set to values like \"8080tcp\", \"80,443\", \"0x1F90\", \"8080 \" + stray unicode, or a value with a unit suffix from a compose file.","commonSituations":"docker-compose / systemd Environment= typos; copying a URL (\"http://\") into the variable; k8s ConfigMap value with quotes or whitespace included; CI env matrices quoting numbers oddly.","solutions":["Set XUI_PORT to a plain decimal integer, e.g. XUI_PORT=8080 (no quotes, units, or protocol).","In compose/systemd files, verify with 'printenv XUI_PORT' or 'systemctl show-environment' that the raw value is numeric.","If unset is intended, remove the variable entirely — unset and empty are treated as 'not configured'."],"exampleFix":"# before (docker-compose.yml)\nenvironment:\n  - XUI_PORT=\"2053\"\n# (quotes themselves are fine, but e.g. XUI_PORT=2053/tcp is not)\n\n# after\nenvironment:\n  - XUI_PORT=2053","handlingStrategy":"validation","validationCode":"if v, ok := os.LookupEnv(\"XUI_PORT\"); ok {\n    if _, err := strconv.Atoi(strings.TrimSpace(v)); err != nil {\n        return fmt.Errorf(\"XUI_PORT must be an integer, got %q\", v)\n    }\n}","typeGuard":"func validPortEnv(v string) bool {\n    v = strings.TrimSpace(v)\n    if v == \"\" { return true } // unset/empty == not configured\n    n, err := strconv.Atoi(v)\n    return err == nil && n >= 1 && n <= 65535\n}","tryCatchPattern":null,"preventionTips":["Validate XUI_PORT in deploy pipelines (compose config lint, helm values schema) as ^[0-9]{1,5}$ plus range check.","Keep the variable purely numeric — no protocol, no units, no lists."],"tags":["config","environment","startup"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}