Skip to main content
This lesson explains how to set the status code on OpenTelemetry spans to reflect success or failure of operations (for example, outgoing HTTP calls). By default OpenTelemetry leaves a span’s status as UNSET until your application or instrumentation sets it explicitly. When an application crash occurs, instrumentation often marks the span as ERROR automatically. For normal request flows you should explicitly set status to OK for success and ERROR for handled failures.
Spans default to UNSET. To represent success or failure in traces, explicitly set the span status to OK or ERROR and record relevant attributes like http.status_code.
Below is an example trace timeline from Jaeger showing a payment service with a failed request span (image preserved from original content):
The image shows a trace timeline from the Jaeger UI, detailing operations of a payment service. It includes spans for validating a card and a failed request to the charge API with an error message related to a connection issue.
Why set span status?
  • Communicates high-level outcome of an operation to downstream analysis tools.
  • Helps filtering and alerting in tracing backends (errors vs. successful traces).
  • Augments other attributes (like http.status_code) for richer context.
Recommended steps for an outgoing HTTP call
  1. Add semantic attributes to the span: HTTP method, URL.
  2. Propagate context (inject headers) before making the request.
  3. Record events for request lifecycle (sending, sent, received).
  4. Set http.status_code as a span attribute using the HTTP response.
  5. Explicitly set span status to OK or ERROR depending on the outcome.
Example: minimal, corrected Python instrumentation and status handling
  • First, configure tracing (tracer provider, resource, and exporter):
  • Then use the tracer when making HTTP calls, set attributes, record events, and set status:
Mapping HTTP responses to span status (recommended defaults)
HTTP resultExample codesRecommended span statusWhy
Success200–299OKSuccessful response; mark span successful.
Client error400–499ERROR (or custom logic)Most client errors are failures; you may treat some codes specially.
Server error500–599ERRORServer-side failures indicate error conditions.
Network/exceptionN/AERRORExceptions and timeouts should mark the span ERROR.
Do not rely solely on span status for debugging. Always record attributes like http.status_code, add meaningful events, and call span.record_exception() when catching exceptions to preserve stack/exception details.
Notes and best practices
  • Import and use Status and StatusCode from opentelemetry.trace and call span.set_status(Status(StatusCode.OK)) or span.set_status(Status(StatusCode.ERROR)).
  • Recording http.status_code as an attribute helps trace UIs and analysis tools provide richer context and filters.
  • Define your application’s notion of “success”—for example, some APIs return 404 or 409 in normal flows; you may decide to mark those as OK in specific contexts.
  • Always propagate context (inject) for distributed traces so downstream services are linked.
After implementing the above and running the application with a successful request, the trace timeline will show the “Request to Charge API” span marked as OK. The Jaeger UI for that trace is shown below (image preserved from original content):
The image shows a Jaeger UI displaying a trace timeline for a payment service. It details various spans, including HTTP method and status code for the "Request to Charge API."
Links and references

Watch Video