Skip to content

otel: handle empty traces and root spans in Jaeger - #4157

Open
crazy-max wants to merge 1 commit into
docker:masterfrom
crazy-max:fix-otelutil-jaeger
Open

crazy-max wants to merge 1 commit into
docker:masterfrom
crazy-max:fix-otelutil-jaeger

Conversation

@crazy-max

Copy link
Copy Markdown
Member

Handle empty traces without panicking during Jaeger conversion. ParseSpanStubs accepts empty or whitespace-only input, but JaegerData unconditionally accesses the first span at

func (s Spans) JaegerData() JaegerData {
roSpans := s.ReadOnlySpans()
// fetch default service.name from default resource for backup
var defaultServiceName string
defaultResource := resource.Default()
if value, exists := defaultResource.Set().Value(attribute.Key("service.name")); exists {
defaultServiceName = value.AsString()
}
data := jaeger.Trace{
TraceID: jaeger.TraceID(roSpans[0].SpanContext().TraceID().String()),
Processes: make(map[jaeger.ProcessID]jaeger.Process),

Return an empty result instead, allowing buildx history trace to reach its existing no trace data error at

spans, err := otelutil.ParseSpanStubs(io.NewSectionReader(ra, 0, ra.Size()))
if err != nil {
return "", nil, err
}
wrapper := struct {
Data []jaeger.Trace `json:"data"`
}{
Data: spans.JaegerData().Data,
}
if len(wrapper.Data) == 0 {
return "", nil, errors.New("no trace data")
}

The new empty-input regression test reproduced the index-out-of-range panic before this fix. This confirms the conversion failure but doesn't establish that BuildKit currently produces empty trace blobs.

Only emit CHILD_OF references for valid parent contexts. The previous conversion at

var refs []Reference
for _, link := range ss.Links() {
refs = append(refs, Reference{
RefType: FollowsFrom,
TraceID: TraceID(link.SpanContext.TraceID().String()),
SpanID: SpanID(link.SpanContext.SpanID().String()),
})
}
refs = append(refs, Reference{
RefType: ChildOf,
TraceID: TraceID(ss.Parent().TraceID().String()),
SpanID: SpanID(ss.Parent().SpanID().String()),
})
adds a parent reference even for root spans, producing all-zero trace and span IDs.

This is visible in the existing bake root-span fixture at

{
"traceID": "0555ce1903feb85770d102846273073b",
"spanID": "d30eea87f2f0241d",
"operationName": "bake",
"references": [
{
"refType": "CHILD_OF",
"traceID": "00000000000000000000000000000000",
"spanID": "0000000000000000"
}
],

Remove that invalid reference while preserving valid parents, span links, and their existing order. Roots without links now serialize with "references": null, which the pinned Jaeger UI normalizes to an empty list.

Return no Jaeger traces for empty input so history trace can report
"no trace data" instead of panicking on the first span.

Only add CHILD_OF references for valid parent contexts, avoiding zero-ID
references on root spans while preserving valid parents and span links.

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
@crazy-max
crazy-max marked this pull request as ready for review October 14, 2026 14:29
@crazy-max crazy-max added this to the v0.39.0 milestone Oct 14, 2026
@tonistiigi

Copy link
Copy Markdown
Member

Maybe we should just remove Jaeger support?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants