XTLS/Xray-core · error
not a StrategyLeastLoadConfig
Error message
not a StrategyLeastLoadConfig
What it means
For a 'leastload' balancing rule, StrategySettings must decode to *StrategyLeastLoadConfig. If the settings message is absent-but-typed differently or the embedded instance is another config type, the assertion fails and the balancer build aborts.
Source
Thrown at app/router/config.go:148
strategy: &LeastPingStrategy{},
fallbackTag: br.FallbackTag,
ohm: ohm,
}, nil
case "roundrobin":
return &Balancer{
selectors: br.OutboundSelector,
strategy: &RoundRobinStrategy{FallbackTag: br.FallbackTag},
fallbackTag: br.FallbackTag,
ohm: ohm,
}, nil
case "leastload":
i, err := br.StrategySettings.GetInstance()
if err != nil {
return nil, err
}
s, ok := i.(*StrategyLeastLoadConfig)
if !ok {
return nil, errors.New("not a StrategyLeastLoadConfig").AtError()
}
leastLoadStrategy := NewLeastLoadStrategy(s)
return &Balancer{
selectors: br.OutboundSelector,
ohm: ohm,
fallbackTag: br.FallbackTag,
strategy: leastLoadStrategy,
}, nil
case "random":
fallthrough
case "":
return &Balancer{
selectors: br.OutboundSelector,
ohm: ohm,
fallbackTag: br.FallbackTag,
strategy: &RandomStrategy{FallbackTag: br.FallbackTag},
}, nil
default:View on GitHub (pinned to 7d214f8b09)
Solutions
- Use the correct settings type for leastload: {"type": "leastload", "settings": {...}} via StrategyLeastLoadConfig fields (costs, baselines, expected status counts)
- Remove strategySettings entirely to use defaults if customization is not needed
- Regenerate the config with a current schema-aware tool
Example fix
// before
"strategy": {
"type": "leastload",
"settings": { "type": "pingconfig" } // wrong settings type
}
// after
"strategy": {
"type": "leastload"
} // defaults, or supply leastload-specific settings Defensive patterns
Strategy: validation
Validate before calling
if strings.EqualFold(br.Strategy, "leastload") && br.StrategySettings != nil {
i, _ := br.StrategySettings.GetInstance()
if _, ok := i.(*router.StrategyLeastLoadConfig); !ok {
return fmt.Errorf("strategySettings must be StrategyLeastLoadConfig for leastload")
}
} Type guard
func isLeastLoadConfig(i interface{}) bool {
_, ok := i.(*router.StrategyLeastLoadConfig)
return ok
} Prevention
- Do not copy settings blocks between different strategy types
- Omit strategySettings to use defaults unless tuning leastload
- After editing strategy config, run xray run -test (config check) before deploying
When it happens
Trigger: Declaring strategy 'leastload' with a strategySettings block whose serialized type is not StrategyLeastLoadConfig (e.g. pasted leastping settings or a random strategy object).
Common situations: Copying strategy blocks between rules of different strategy types; JSON configs hand-migrated between versions where settings type names changed.
Related errors
- unrecognized balancer type
- balancer %s not found
- duplicate balancer tag
- balancing strategy returns empty tag
- unable to select outbounds
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/98aa4bf889aa6bb0.
Report an issue: GitHub.