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

  1. Set XUI_PORT to a plain decimal integer, e.g. XUI_PORT=8080 (no quotes, units, or protocol).
  2. In compose/systemd files, verify with 'printenv XUI_PORT' or 'systemctl show-environment' that the raw value is numeric.
  3. 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

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


AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15). Data as JSON: /api/errors/a714db3493986d1d. Report an issue: GitHub.