jaegertracing/jaeger · error

cannot find query interceptor extension %q (make sure it is

Error message

cannot find query interceptor extension %q (make sure it is defined under extensions: and enabled in service.extensions)

What it means

Resolve looks up each requested query interceptor by component ID in the OpenTelemetry collector host's extension map. The ID was configured for the query service but no extension with that ID exists (or it exists but was not enabled in service.extensions), so the lookup fails. Jaeger tells you exactly which YAML keys to fix.

Source

Thrown at cmd/jaeger/internal/extension/jaegerquery/queryinterceptor/resolver.go:40

)

// Resolve looks up the extensions named by ids on the collector host and asserts
// that each implements the public Interceptor contract, returning them in order.
// An empty ids slice yields no interceptors (and no error).
//
// This mirrors the OpenTelemetry Collector's auth-extension mechanism: a
// component references an extension by component.ID in its config and resolves
// it from host.GetExtensions() at start time.
func Resolve(host component.Host, ids []component.ID) ([]pub.Interceptor, error) {
	if len(ids) == 0 {
		return nil, nil
	}
	extensions := host.GetExtensions()
	interceptors := make([]pub.Interceptor, 0, len(ids))
	for _, id := range ids {
		comp, ok := extensions[id]
		if !ok {
			return nil, fmt.Errorf(
				"cannot find query interceptor extension %q (make sure it is defined under extensions: and enabled in service.extensions)",
				id,
			)
		}
		interceptor, ok := comp.(pub.Interceptor)
		if !ok {
			return nil, fmt.Errorf("extension %q does not implement queryinterceptor.Interceptor", id)
		}
		interceptors = append(interceptors, interceptor)
	}
	return interceptors, nil
}

View on GitHub (pinned to 806f444784)

Solutions

  1. Add the extension under the `extensions:` section of the collector config with the exact ID referenced by jaeger_query.
  2. Enable it by listing the same ID under `service.extensions`.
  3. Fix typos so the interceptor ID in jaeger_query config matches the defined extension ID exactly.
  4. Validate the full config with the collector's config validation before starting.

Example fix

// before
extensions:
  jaeger_query/xyz: {}
service:
  extensions: []
// after
extensions:
  jaeger_query/xyz: {}
service:
  extensions: [jaeger_query/xyz]
Defensive patterns

Strategy: validation

Validate before calling

// preflight: every interceptor id must be both defined and enabled
defined := set(config.Extensions)
enabled := set(config.Service.Extensions)
for _, id := range config.JaegerQuery.Interceptors {
    if !defined[id] || !enabled[id] {
        return fmt.Errorf("interceptor %q not defined/enabled", id)
    }
}

Try / catch

interceptors, err := resolver.Resolve(host, ids)
if err != nil {
    return fmt.Errorf("starting jaeger_query: %w", err) // fatal at startup by design
}

Prevention

When it happens

Trigger: queryinterceptor.Resolve is called during extension Start with a list of interceptor IDs (from the jaeger_query extension config) where extensions[id] is missing from host.GetExtensions() — either the extension is not defined under `extensions:` or not listed under `service.extensions`.

Common situations: Typo between the ID under `extensions:` and the jaeger_query interceptor list; forgetting to add the new extension to `service.extensions` so it is defined but never instantiated; renaming an extension config key; copy-pasting config between deployments where the extension was removed.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/ac0c954d42e872c4. Report an issue: GitHub.