Skip to content
Latchkey

OpenTelemetry Python spans not recording (no SDK TracerProvider) in CI

The OpenTelemetry API returns a no-op tracer until an SDK TracerProvider is set. If tests only install/import opentelemetry-api (or never call set_tracer_provider), every span is non-recording and assertions on span data fail.

What this error means

A test asserting on captured spans finds none, or span.is_recording() returns False. The exporter/in-memory span list is empty even though the code creates spans.

python
>>> from opentelemetry import trace
>>> span = trace.get_tracer(__name__).start_span("op")
>>> span.is_recording()
False   # no SDK TracerProvider set - NonRecordingSpan

Common causes

No SDK TracerProvider is configured

Without trace.set_tracer_provider(TracerProvider(...)), the global provider is the API default that returns NonRecordingSpans, so nothing is recorded or exported.

opentelemetry-sdk is not installed

Only opentelemetry-api is a dependency; the opentelemetry-sdk package that provides the real provider and processors is missing in the CI environment.

How to fix it

Configure the SDK in test setup

  1. Install opentelemetry-sdk alongside the API.
  2. Set a TracerProvider with an InMemorySpanExporter for assertions.
  3. Read exporter.get_finished_spans() in the test.
conftest.py
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter

provider = TracerProvider()
exporter = InMemorySpanExporter()
provider.add_span_processor(SimpleSpanProcessor(exporter))
trace.set_tracer_provider(provider)

Add the SDK as a test dependency

Pin the SDK to the same version as the API so the provider is available in CI.

Terminal
pip install opentelemetry-sdk

How to prevent it

  • Install opentelemetry-sdk, not just the API, when tests assert on spans.
  • Set the TracerProvider in conftest before any span is created.
  • Use InMemorySpanExporter to make span assertions deterministic.

Frequently asked questions

What causes "span.is_recording() is False"?
Without trace.set_tracer_provider(TracerProvider(...)), the global provider is the API default that returns NonRecordingSpans, so nothing is recorded or exported.
How do I fix span.is_recording() is False?
Configure the SDK in test setup

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card