jaegertracing/jaeger · error
cannot assign unique span ID, too many spans in the trace
Error message
cannot assign unique span ID, too many spans in the trace
What it means
errTypedConstant reports that a filter constant declares a type (via constantKind, by wire type) that this backend cannot route to a typed stored value, because all attribute values are indexed as keywords here. Honoring the declared type would silently match more than the user asked, so only untyped constants are served; the filter is rejected with tracestore.ErrFilterUnsupported. Typed attribute indexing (RFC 0015) is the roadmap fix.
Source
Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/adjuster/spaniduniquifier.go:16
// Copyright (c) 2019 The Jaeger Authors.
// Copyright (c) 2017 Uber Technologies, Inc.
// SPDX-License-Identifier: Apache-2.0
package adjuster
import (
"errors"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/ptrace"
"github.com/jaegertracing/jaeger/internal/jptrace"
)
var errTooManySpans = errors.New("cannot assign unique span ID, too many spans in the trace")
// DeduplicateClientServerSpanIDs returns an adjuster that changes span ids for server
// spans (i.e. spans with tag: span.kind == server) if there is another
// client span that shares the same span ID. This is needed to deal with
// Zipkin-style clients that reuse the same span ID for both client and server
// side of an RPC call. Jaeger UI expects all spans to have unique IDs.
//
// Any issues encountered during adjustment are recorded as warnings in the
// span.
func DeduplicateClientServerSpanIDs() Adjuster {
return Func(func(traces ptrace.Traces) {
adjuster := spanIDDeduper{
spansByID: make(map[pcommon.SpanID][]ptrace.Span),
maxUsedID: pcommon.NewSpanIDEmpty(),
}
adjuster.adjust(traces)
})
}View on GitHub (pinned to 806f444784)
Solutions
- Send the constant untyped (let the expression carry a plain string/untyped constant) so it matches the keyword-stored value.
- Enable or migrate to typed attribute indexing (RFC 0015) if exact typed matching is required.
- Catch errors.Is(err, tracestore.ErrFilterUnsupported) and surface that typed constants are not supported by this backend.
Example fix
// before attr.status (typed int64) == 200 // after attr.status == "200"
Defensive patterns
Strategy: validation
Validate before calling
func untypedConstant(e expression.Expression) bool {
return constantKind(e) == "untyped" // only untyped constants are served
} Try / catch
q, err := buildFilterQuery(...)
if errors.Is(err, tracestore.ErrFilterUnsupported) && strings.Contains(err.Error(), "untyped constants only") {
// strip the declared type and resend the constant untyped
} Prevention
- Send untyped (string) constants when targeting a keyword-only Elasticsearch backend.
- Strip protobuf-assigned wire types before building filter constants.
- Plan migration to typed attribute indexing (RFC 0015) for typed matching.
When it happens
Trigger: Submitting a filter whose constant is explicitly typed (e.g. an int64/float64/bool-typed attribute value) from untypedText, fieldText, or lengthOfTime, where the backend cannot route to a typed value in a keyword-only index.
Common situations: Clients that always attach wire types to attribute values (protobuf defaults) hitting a keyword-only Elasticsearch mapping; filters migrated from typed backends (Cassandra with typed columns) to Elasticsearch; RFC 0005 §5.4 typed matching expectations.
Related errors
- file must begin with '['
- empty configuration
- at least one storage backend is required
- max spans count reached
- only one of basic auth (--es.username/--es.password), --es.t
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/536f2441bcd9a9b5.
Report an issue: GitHub.