XTLS/Xray-core · error

unsupported router implementation

Error message

unsupported router implementation

What it means

The gRPC OverrideBalancerTarget handler type-asserts the registered router to routing.BalancerOverrider. Only the real app/router Router (or a custom implementation providing SetOverrideTarget/GetOverrideTarget/GetPrincipleTarget) satisfies it; anything else gets this error. It signals an environment/wiring problem, not a user-input problem.

Source

Thrown at app/router/command/command.go:53

	if pt, ok := s.router.(routing.BalancerPrincipleTarget); ok {
		{
			res, err := pt.GetPrincipleTarget(request.GetTag())
			if err != nil {
				errors.LogInfoInner(ctx, err, "unable to obtain principle target")
			} else {
				ret.Balancer.PrincipleTarget = &PrincipleTargetInfo{Tag: res}
			}
		}
	}
	return &ret, nil
}

func (s *routingServer) OverrideBalancerTarget(ctx context.Context, request *OverrideBalancerTargetRequest) (*OverrideBalancerTargetResponse, error) {
	if bo, ok := s.router.(routing.BalancerOverrider); ok {
		return &OverrideBalancerTargetResponse{}, bo.SetOverrideTarget(request.BalancerTag, request.Target)
	}
	return nil, errors.New("unsupported router implementation")
}

func (s *routingServer) AddRule(ctx context.Context, request *AddRuleRequest) (*AddRuleResponse, error) {
	if bo, ok := s.router.(routing.Router); ok {
		return &AddRuleResponse{}, bo.AddRule(request.Config, request.ShouldAppend)
	}
	return nil, errors.New("unsupported router implementation")
}

func (s *routingServer) RemoveRule(ctx context.Context, request *RemoveRuleRequest) (*RemoveRuleResponse, error) {
	if bo, ok := s.router.(routing.Router); ok {
		return &RemoveRuleResponse{}, bo.RemoveRule(request.RuleTag)
	}
	return nil, errors.New("unsupported router implementation")
}

func (s *routingServer) ListRule(ctx context.Context, request *ListRuleRequest) (*ListRuleResponse, error) {
	if bo, ok := s.router.(routing.Router); ok {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Register the standard app/router instance as the handler for routing.RoutingService
  2. If using a custom router, implement SetOverrideTarget/GetOverrideTarget/GetPrincipleTarget on it
  3. Align versions of xray-core packages so command and router come from the same release

Example fix

// before
command.NewRoutingServer(mockRouter, nil) // mock lacks BalancerOverrider

// after
command.NewRoutingServer(realRouter, routingStats) // app/router.Router implements it
Defensive patterns

Strategy: type-guard

Type guard

func supportsOverride(r interface{}) bool {
    _, ok := r.(routing.BalancerOverrider)
    return ok
}

Prevention

When it happens

Trigger: RoutingService server constructed with a router implementation lacking the BalancerOverrider interface (mocks in tests, alternative router packages, older Router version).

Common situations: Unit tests injecting a fake router; forks that replaced the router; version mismatch where the command package is newer than the router implementation.

Related errors


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