XTLS/Xray-core · error

Routing statistics not enabled.

Error message

Routing statistics not enabled.

What it means

SubscribeRoutingStats requires a stats channel for routing events; the server was constructed (or the app booted) without one, so streaming is refused. The channel is only created when routing stats are enabled in the policy/stats configuration path.

Source

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

func (s *routingServer) TestRoute(ctx context.Context, request *TestRouteRequest) (*RoutingContext, error) {
	if request.RoutingContext == nil {
		return nil, errors.New("Invalid routing request.")
	}
	route, err := s.router.PickRoute(AsRoutingContext(request.RoutingContext))
	if err != nil {
		return nil, err
	}
	if request.PublishResult && s.routingStats != nil {
		ctx, _ := context.WithTimeout(context.Background(), 4*time.Second)
		s.routingStats.Publish(ctx, route)
	}
	return AsProtobufMessage(request.FieldSelectors)(route), nil
}

func (s *routingServer) SubscribeRoutingStats(request *SubscribeRoutingStatsRequest, stream RoutingService_SubscribeRoutingStatsServer) error {
	if s.routingStats == nil {
		return errors.New("Routing statistics not enabled.")
	}
	genMessage := AsProtobufMessage(request.FieldSelectors)
	subscriber, err := stats.SubscribeRunnableChannel(s.routingStats)
	if err != nil {
		return err
	}
	defer stats.UnsubscribeClosableChannel(s.routingStats, subscriber)
	for {
		select {
		case value, ok := <-subscriber:
			if !ok {
				return errors.New("Upstream closed the subscriber channel.")
			}
			route, ok := value.(routing.Route)
			if !ok {
				return errors.New("Upstream sent malformed statistics.")
			}
			err := stream.Send(genMessage(route))

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Enable routing statistics in the instance (add stats + policy configuration) and restart
  2. Ensure the RoutingService is created through the normal app wiring so routingStats is injected
  3. If embedding, pass a non-nil stats.Channel to NewRoutingServer

Example fix

// before
command.NewRoutingServer(router, nil) // SubscribeRoutingStats -> not enabled

// after
statsCh := statsChannelFromApp // obtained via features/stats
command.NewRoutingServer(router, statsCh)
Defensive patterns

Strategy: validation

Validate before calling

// Check the feature before subscribing:
if statsFeature == nil || !statsFeature.Running() {
    return fmt.Errorf("routing stats unavailable; enable stats in config")
}

Prevention

When it happens

Trigger: Streaming SubscribeRoutingStats when s.routingStats == nil: stats feature not registered or routing statistics not enabled in config.

Common situations: Calling SubscribeRoutingStats on an instance whose stats service is absent; policy level stats not enabled; NewRoutingServer called directly with nil routingStats in embedded setups.

Related errors


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