What are you trying to achieve?
During the Logs SIG meeting on 2026-03-10, we discussed whether the tracing API should offer a more ergonomic way to record an operation's final error at the point where the span ends.
One possible direction would be to add an optional error/exception parameter, or a language-appropriate equivalent, to Span.End.
The goal is to make it easier for instrumentation to follow the error recording semantic conventions for spans when the final outcome of the operation is only known immediately before the span is finished.
Today, instrumentation often needs multiple explicit calls to:
- set
error.type
- set span status
- call
End
This is repetitive, easy to miss, and can lead to inconsistent adoption across languages and instrumentation libraries.
Additional context
This pattern is common in Go instrumentation. For example, OpenTelemetry Go Contrib has code like this:
ctx, span := tracer.Start(ctx, "my-span")
// ...
if err != nil {
span.SetAttributes(otelsemconv.ErrorType(err))
span.SetStatus(codes.Error, err.Error())
}
span.End()
With an error-aware End, this could look like:
ctx, span := tracer.Start(ctx, "my-span")
// ...
if err != nil {
span.End(trace.WithError(err))
} else {
span.End()
}
Another possible design would be a dedicated convenience method on Span, for example SetErrorStatus(err):
ctx, span := tracer.Start(ctx, "my-span")
defer span.End()
// ...
if err != nil {
span.SetErrorStatus(err)
}
That shape may be more convenient in languages where End is typically registered at span creation time (for example, defer in Go, using in .NET, or with in Python). It would also fit the existing API style of SetStatus, SetAttributes, and similar mutating methods.
On the other hand, adding a new Span method may be a more disruptive API change in some languages than extending End with optional arguments or options. The tradeoffs may therefore depend on language ergonomics and API stability constraints.
I suspect multiple languages would benefit from a convenience API here, using whatever surface is most idiomatic for that language. This feels analogous to #4824 ("Add optional Exception parameter to Emit LogRecord"), but for tracing.
This is also related to the ongoing discussion about deprecating Span.RecordException:
However, I do not think this should be treated as a direct replacement for Span.RecordException. Recording an exception event and marking a span's final outcome as failed are related but distinct concerns. A convenience API in this area would primarily help instrumentation apply the span error-recording conventions consistently at the end of an operation.
Questions for discussion
- Should the spec standardize one shape across languages, or only standardize the behavior and let each language choose an idiomatic API?
- Should this be implemented as SDK functionality, or can it be specified as an API-level helper/default implementation? Adding it at the API layer may reduce flexibility, but it could also allow new functionality without requiring all existing SDK span implementations to change immediately. E.g. if the SDK does not provide native support, then the spec may allow a default implementation that sets attributes and status.
- Should there an optional parameter to set
error.type and maybe also status description if the value calculated by the SDK would not be ideal (like name of the exception type and exception message)?
Tip: React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.
What are you trying to achieve?
During the Logs SIG meeting on 2026-03-10, we discussed whether the tracing API should offer a more ergonomic way to record an operation's final error at the point where the span ends.
One possible direction would be to add an optional error/exception parameter, or a language-appropriate equivalent, to
Span.End.The goal is to make it easier for instrumentation to follow the error recording semantic conventions for spans when the final outcome of the operation is only known immediately before the span is finished.
Today, instrumentation often needs multiple explicit calls to:
error.typeEndThis is repetitive, easy to miss, and can lead to inconsistent adoption across languages and instrumentation libraries.
Additional context
This pattern is common in Go instrumentation. For example, OpenTelemetry Go Contrib has code like this:
With an error-aware
End, this could look like:Another possible design would be a dedicated convenience method on
Span, for exampleSetErrorStatus(err):That shape may be more convenient in languages where
Endis typically registered at span creation time (for example,deferin Go,usingin .NET, orwithin Python). It would also fit the existing API style ofSetStatus,SetAttributes, and similar mutating methods.On the other hand, adding a new
Spanmethod may be a more disruptive API change in some languages than extendingEndwith optional arguments or options. The tradeoffs may therefore depend on language ergonomics and API stability constraints.I suspect multiple languages would benefit from a convenience API here, using whatever surface is most idiomatic for that language. This feels analogous to #4824 ("Add optional
Exceptionparameter to Emit LogRecord"), but for tracing.This is also related to the ongoing discussion about deprecating
Span.RecordException:However, I do not think this should be treated as a direct replacement for
Span.RecordException. Recording an exception event and marking a span's final outcome as failed are related but distinct concerns. A convenience API in this area would primarily help instrumentation apply the span error-recording conventions consistently at the end of an operation.Questions for discussion
error.typeand maybe also status description if the value calculated by the SDK would not be ideal (like name of the exception type and exception message)?Tip: React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding
+1orme too, to help us triage it. Learn more here.