MHSanaei/3x-ui · error
parse XUI_PORT: %w
Error message
parse XUI_PORT: %w
What it means
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.
Source
Thrown at internal/config/config.go:120
// IsDebug returns true if debug mode is enabled via the XUI_DEBUG environment variable.
func IsDebug() bool {
return os.Getenv("XUI_DEBUG") == "true"
}
// IsSkipHSTS returns true if skipping HSTS mode is enabled via the XUI_SKIP_HSTS environment variable.
func IsSkipHSTS() bool {
return os.Getenv("XUI_SKIP_HSTS") == "true"
}
func GetPortOverride() (port int, configured bool, err error) {
value, ok := os.LookupEnv("XUI_PORT")
if !ok || strings.TrimSpace(value) == "" {
return 0, false, nil
}
port, err = strconv.Atoi(strings.TrimSpace(value))
if err != nil {
return 0, true, fmt.Errorf("parse XUI_PORT: %w", err)
}
if port < 1 || port > 65535 {
return 0, true, fmt.Errorf("XUI_PORT must be between 1 and 65535")
}
return port, true, nil
}
// GetBinFolderPath returns the path to the binary folder, defaulting to "bin" if not set via XUI_BIN_FOLDER.
func GetBinFolderPath() string {
binFolderPath := os.Getenv("XUI_BIN_FOLDER")
if binFolderPath == "" {
binFolderPath = "bin"
}
return binFolderPath
}
func getBaseDir() string {View on GitHub (pinned to ad32144c42)
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'.
Example fix
# before (docker-compose.yml) environment: - XUI_PORT="2053" # (quotes themselves are fine, but e.g. XUI_PORT=2053/tcp is not) # after environment: - XUI_PORT=2053
Defensive patterns
Strategy: validation
Validate before calling
if v, ok := os.LookupEnv("XUI_PORT"); ok {
if _, err := strconv.Atoi(strings.TrimSpace(v)); err != nil {
return fmt.Errorf("XUI_PORT must be an integer, got %q", v)
}
} Type guard
func validPortEnv(v string) bool {
v = strings.TrimSpace(v)
if v == "" { return true } // unset/empty == not configured
n, err := strconv.Atoi(v)
return err == nil && n >= 1 && n <= 65535
} Prevention
- 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.
When it happens
Trigger: XUI_PORT set to values like "8080tcp", "80,443", "0x1F90", "8080 " + stray unicode, or a value with a unit suffix from a compose file.
Common situations: 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.
Related errors
- XUI_PORT must be between 1 and 65535
- XUI_DB_TYPE=postgres but XUI_DB_DSN is empty
- postgres unreachable after %d attempts: %w
- Failed to reserve test ports: %w
- Failed to create test config path: %w
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/a714db3493986d1d.
Report an issue: GitHub.