XTLS/Xray-core · error
duplicate balancer tag
Error message
duplicate balancer tag
What it means
While (re)building balancers, two balancingRule entries declare the same tag. Balancers are keyed by tag in a map, so duplicates would silently overwrite each other; the loader rejects instead. Note the early return leaks already-built balancers' webhooks state, but config load fails anyway.
Source
Thrown at app/router/router.go:139
}
func (r *Router) ReloadRules(config *Config, shouldAppend bool) error {
r.mu.Lock()
defer r.mu.Unlock()
if !shouldAppend {
for _, rule := range r.rules {
if rule.Webhook != nil {
rule.Webhook.Close()
}
}
r.balancers = make(map[string]*Balancer, len(config.BalancingRule))
r.rules = make([]*Rule, 0, len(config.Rule))
}
for _, rule := range config.BalancingRule {
_, found := r.balancers[rule.Tag]
if found {
return errors.New("duplicate balancer tag")
}
balancer, err := rule.Build(r.ohm, r.dispatcher)
if err != nil {
return err
}
balancer.InjectContext(r.ctx)
r.balancers[rule.Tag] = balancer
}
startIdx := len(r.rules)
closeNewWebhooks := func() {
for i := startIdx; i < len(r.rules); i++ {
if r.rules[i].Webhook != nil {
r.rules[i].Webhook.Close()
}
}
r.rules = r.rules[:startIdx]
}View on GitHub (pinned to 7d214f8b09)
Solutions
- Give each balancingRule a unique tag
- In append mode, only include new balancer tags not already loaded
- Lint the config for duplicate tags before submit
Example fix
// before
"balancingRule": [
{ "tag": "bal", "selector": ["a"] },
{ "tag": "bal", "selector": ["b"] }
]
// after
"balancingRule": [
{ "tag": "bal-a", "selector": ["a"] },
{ "tag": "bal-b", "selector": ["b"] }
] Defensive patterns
Strategy: validation
Validate before calling
seen := map[string]bool{}
for _, b := range cfg.BalancingRule {
if seen[b.Tag] { return fmt.Errorf("duplicate balancer tag %q", b.Tag) }
seen[b.Tag] = true
} Prevention
- Deduplicate balancer tags in config linting before deploy
- In append reloads, diff new tags against already-registered ones
- Use distinct, meaningful tag names per selector group
When it happens
Trigger: ReloadRules/AddRule config containing two balancingRule blocks with identical tag values; append-mode reload re-adding an existing balancer tag.
Common situations: Copy-pasted balancer blocks in JSON; append reloads (shouldAppend=true) that repeat tags already registered.
Related errors
- not a StrategyLeastLoadConfig
- unrecognized balancer type
- balancer %s not found
- duplicate ruleTag %s
- balancing strategy returns empty tag
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/08deab20821d70a3.
Report an issue: GitHub.