XTLS/Xray-core · error · errors.Error

Cannot get depended features

Error message

Cannot get depended features

What it means

Returned by New() for the classic observatory (app/observatory/observer.go:238) when core.RequireFeatures cannot resolve outbound.Manager and routing.Dispatcher from the instance context. The observer dispatches its probes through the routing dispatcher and enumerates outbounds through the manager, so without both features it cannot start.

Source

Thrown at app/observatory/observer.go:238

func (o *Observer) findStatusLocationLockHolderOnly(outbound string) int {
	for i, v := range o.status {
		if v.OutboundTag == outbound {
			return i
		}
	}
	return -1
}

func New(ctx context.Context, config *Config) (*Observer, error) {
	var outboundManager outbound.Manager
	var dispatcher routing.Dispatcher
	err := core.RequireFeatures(ctx, func(om outbound.Manager, rd routing.Dispatcher) {
		outboundManager = om
		dispatcher = rd
	})
	if err != nil {
		return nil, errors.New("Cannot get depended features").Base(err)
	}
	return &Observer{
		config:     config,
		ctx:        ctx,
		ohm:        outboundManager,
		dispatcher: dispatcher,
	}, nil
}

func init() {
	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
		return New(ctx, config.(*Config))
	}))
}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Include the proxyman app in the instance's app list before creating the observatory.
  2. Check the Base error to see which required feature was missing.
  3. If configuring via JSON, ensure the observatory block sits at the top level of the same config as outbounds.

Example fix

// before
cfg.App = append(cfg.App, serial.ToTypedMessage(&observatory.Config{ ... }))

// after
cfg.App = append(cfg.App,
  serial.ToTypedMessage(&proxyman.Config{}),
  serial.ToTypedMessage(&observatory.Config{ ... }),
)
Defensive patterns

Strategy: validation

Validate before calling

// verify required features before constructing the observer
if _, ok := core.GetFeature(ctx, outbound.ManagerType()).(outbound.Manager); !ok {
    return errors.New("outbound manager feature missing")
}

Try / catch

obs, err := observatory.New(ctx, cfg)
if err != nil {
    return fmt.Errorf("observatory unavailable on this instance: %w", err)
}

Prevention

When it happens

Trigger: Constructing an Observatory on a core instance that lacks the proxyman app or where feature registration did not complete before the observatory initializes. In JSON-driven configs proxyman is always present, so this is essentially a library-embedding or app-ordering problem.

Common situations: Custom xray-core builds that assemble core.Config.App manually and forget proxyman; or third-party tools that lazily start apps and race the observatory's RequireFeatures.

Related errors


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