XTLS/Xray-core · critical

this config should be run on version %s or lower

Error message

this config should be run on version %s or lower

What it means

Returned by version.New when the config declares a MaxVersion strictly lower than the running core version — i.e. the config is known to be incompatible with cores newer than MaxVersion. compareVersions(MaxVersion, CoreVersion) < 0 triggers it. This usually means the core binary is newer than the config format expects (e.g. pre-release config used on a stable, changed core).

Source

Thrown at app/version/version.go:33

}

func New(ctx context.Context, config *Config) (*Version, error) {
	if config.MinVersion != "" {
		result, err := compareVersions(config.MinVersion, config.CoreVersion)
		if err != nil {
			return nil, err
		}
		if result > 0 {
			return nil, errors.New("this config must be run on version ", config.MinVersion, " or higher")
		}
	}
	if config.MaxVersion != "" {
		result, err := compareVersions(config.MaxVersion, config.CoreVersion)
		if err != nil {
			return nil, err
		}
		if result < 0 {
			return nil, errors.New("this config should be run on version ", config.MaxVersion, " or lower")
		}
	}
	return &Version{config: config, ctx: ctx}, nil
}

func compareVersions(v1, v2 string) (int, error) {
	// Split version strings into components
	v1Parts := strings.Split(v1, ".")
	v2Parts := strings.Split(v2, ".")

	// Pad shorter versions with zeros
	for len(v1Parts) < len(v2Parts) {
		v1Parts = append(v1Parts, "0")
	}
	for len(v2Parts) < len(v1Parts) {
		v2Parts = append(v2Parts, "0")
	}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Regenerate or edit the config to raise/remove maxVersion once compatibility with the new core is confirmed.
  2. Alternatively downgrade the xray-core binary to the pinned line.
  3. Keep configs free of version pins unless a known incompatibility exists, so routine core upgrades do not brick startup.

Example fix

// before (config)
"maxVersion": "24.11.30" // core is 25.8.15 -> startup fails

// after
"maxVersion": "" // or bump to current core version
Defensive patterns

Strategy: validation

Validate before calling

if cfg.MaxVersion != "" {
    if c, err := versionCompare(cfg.MaxVersion, coreVer); err == nil && c < 0 {
        // regenerate config without the pin, or downgrade binary
    }
}

Type guard

func isNumericVersion(v string) bool {
    if v == "" { return false }
    for _, p := range strings.Split(v, ".") {
        if _, err := strconv.Atoi(p); err != nil { return false }
    }
    return true
}

Try / catch

_, err := version.New(ctx, vcfg)
if err != nil { /* config/core mismatch: align versions before retry */ }

Prevention

When it happens

Trigger: Running a config that pins maxVersion (typical of configs generated for a specific release line) on a newer xray build; downgrading a config's expected core while keeping an upgraded binary.

Common situations: Rolling back a panel that emits maxVersion pins while the server binary stayed upgraded; using experimental configs on stable cores after a breaking release.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/86d162b4dff6cc63. Report an issue: GitHub.