XTLS/Xray-core · error

empty balancer tag

Error message

empty balancer tag

What it means

Thrown by BalancingRule.Build when a routing balancer rule's tag is an empty string. The balancer tag is the identifier that routing rules reference in their balancerTag field; an empty tag cannot be referenced, so the rule is rejected before selector/strategy validation. Selectors are checked next ('empty selector list'), so a rule reaching this error specifically failed the tag check.

Source

Thrown at infra/conf/router.go:31

)

// StrategyConfig represents a strategy config
type StrategyConfig struct {
	Type     string           `json:"type"`
	Settings *json.RawMessage `json:"settings"`
}

type BalancingRule struct {
	Tag         string         `json:"tag"`
	Selectors   StringList     `json:"selector"`
	Strategy    StrategyConfig `json:"strategy"`
	FallbackTag string         `json:"fallbackTag"`
}

// Build builds the balancing rule
func (r *BalancingRule) Build() (*router.BalancingRule, error) {
	if r.Tag == "" {
		return nil, errors.New("empty balancer tag")
	}
	if len(r.Selectors) == 0 {
		return nil, errors.New("empty selector list")
	}

	r.Strategy.Type = strings.ToLower(r.Strategy.Type)
	switch r.Strategy.Type {
	case "":
		r.Strategy.Type = strategyRandom
	case strategyRandom, strategyLeastLoad, strategyLeastPing, strategyRoundRobin:
	default:
		return nil, errors.New("unknown balancing strategy: " + r.Strategy.Type)
	}

	settings := []byte("{}")
	if r.Strategy.Settings != nil {
		settings = ([]byte)(*r.Strategy.Settings)
	}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Give each balancer a unique non-empty tag, e.g. "balancer0"
  2. Reference that exact tag from routing rules via balancerTag

Example fix

// before
"balancers": [ { "selector": ["out"] } ]
// after
"balancers": [ { "tag": "balancer0", "selector": ["out"] } ]
Defensive patterns

Strategy: validation

Validate before calling

for _, b := range routing.Balancers {
	if strings.TrimSpace(b.Tag) == "" {
		return fmt.Errorf("balancer at index %d has an empty tag", i)
	}
}

Prevention

When it happens

Trigger: Declaring routing.balancers[] entry without a tag field, or with tag set to "".

Common situations: Hand-editing balancer lists and deleting the tag while keeping the entry; config generators emitting balancers without tags when no name was supplied.

Related errors


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