jaegertracing/jaeger · warning
ErrUnsupported
ErrUnsupported
Error message
remote storage does not report its capabilities: %w
What it means
TraceReader.SearchCapabilities queries the remote storage for its search capabilities. If the server returns gRPC Unimplemented (older backend lacking the GetCapabilities RPC), the reader reports both search capabilities as unsupported by wrapping errors.ErrUnsupported.
Source
Thrown at internal/storage/v2/grpc/tracereader.go:61
return &TraceReader{
client: storage.NewTraceReaderClient(conn),
capabilities: storage.NewCapabilitiesClient(conn),
}
}
// SearchCapabilities asks the remote backend what it supports and remembers the answer. A
// backend that does not serve the Capabilities service answers UNIMPLEMENTED, which becomes
// ErrUnsupported, so the caller assumes the least capable backend and a backend predating the
// service keeps working (RFC 0013 §3.6).
func (tr *TraceReader) SearchCapabilities(ctx context.Context) (tracestore.SearchCapabilities, error) {
if caps := tr.cachedCaps.Load(); caps != nil {
return *caps, nil
}
resp, err := tr.capabilities.GetCapabilities(ctx, &storage.GetCapabilitiesRequest{})
if err != nil {
if status.Code(err) == codes.Unimplemented {
return tracestore.SearchCapabilities{}, fmt.Errorf(
"remote storage does not report its capabilities: %w", errors.ErrUnsupported,
)
}
return tracestore.SearchCapabilities{}, err
}
caps := tracestore.SearchCapabilities{
WithoutServiceName: resp.GetSearch().GetWithoutServiceName(),
SameSpanConjunction: resp.GetSearch().GetSameSpanConjunction(),
Filter: fromProtoFilterCapabilities(resp.GetSearch().GetFilter()),
}
tr.cachedCaps.Store(&caps)
return caps, nil
}
func (tr *TraceReader) GetTraces(
ctx context.Context,
traceIDs ...tracestore.GetTraceParams,
) iter.Seq2[[]ptrace.Traces, error] {View on GitHub (pinned to 806f444784)
Solutions
- Upgrade the remote storage server to a jaeger version implementing GetCapabilities
- Treat the ErrUnsupported result as 'no search capabilities' and degrade gracefully
- Check status.Code(err) == codes.Unimplemented in callers to branch on unsupported
- Remove the version-skewed proxy/adapter between query and storage
Example fix
// before
caps, err := reader.SearchCapabilities(ctx)
if err != nil { return err }
// after
caps, err := reader.SearchCapabilities(ctx)
if errors.Is(err, errors.ErrUnsupported) {
caps = tracestore.SearchCapabilities{} // treat as unsupported
} Defensive patterns
Strategy: fallback
Type guard
func isUnsupported(err error) bool {
return errors.Is(err, errors.ErrUnsupported)
} Try / catch
caps, err := reader.SearchCapabilities(ctx)
if err != nil {
if errors.Is(err, errors.ErrUnsupported) {
caps = tracestore.SearchCapabilities{}
} else {
return err
}
} Prevention
- Align jaeger component versions across query and storage
- Check remote storage version supports storage/v2 APIs
- Document capability requirements for custom plugins
When it happens
Trigger: Calling SearchCapabilities against a remote storage server built from an older jaeger version or a plugin that does not implement storage/v2 GetCapabilities.
Common situations: Version skew: jaeger query component newer than the remote storage plugin; using v1-only remote storage backends; proxying to a backend without capability reporting.
Related errors
- failed to get dependencies: %w
- failed to execute GetServices: %w
- failed to execute GetOperations: %w
- failed to execute FindTraceIDs: %w
- trace not found
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/07d974f634d9f4b2.
Report an issue: GitHub.