redis/redis-py · error · RuntimeError
Metrics are enabled but no global MeterProvider is…
Error message
Metrics are enabled but no global MeterProvider is configured.
Set up OpenTelemetry before initializing redis-py observability:
from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
# Create exporter
exporter = OTLPMetricExporter(
endpoint='http://localhost:4318/v1/metrics'
)
# Create reader
reader = PeriodicExportingMetricReader(
exporter=exporter,
export_interval_millis=10000
)
# Create and set global provider
provider = MeterProvider(metric_readers=[reader])
metrics.set_meter_provider(provider)
# Now initialize redis-py observability
from redis.observability import get_observability_instance, OTelConfig
otel = get_observability_instance()
otel.init(OTelConfig(enable_metrics=True)) What it means
Raised as RuntimeError by OTelProviderManager.get_meter_provider() (redis/observability/providers.py:90) when metrics are enabled and the SDK is importable, but the global MeterProvider is still the OpenTelemetry default NoOpMeterProvider. redis-py deliberately uses the application-owned global provider (see module docstring) rather than installing its own, so if nothing has called metrics.set_meter_provider(...) the manager refuses to silently no-op and raises with a copy-pasteable setup recipe.
Solutions
- Set a real global MeterProvider BEFORE initializing redis-py observability, exactly as the embedded recipe shows: build an OTLPMetricExporter, wrap it in a PeriodicExportingMetricReader, construct MeterProvider(metric_readers=[reader]), then metrics.set_meter_provider(provider).
- Reorder application startup so the OTel SDK/provider setup runs before get_observability_instance().init(...).
- If you only want local/no-op metrics, disable metrics by passing OTelConfig(enabled_telemetry=[]) (or TelemetryOption(0)) so get_meter_provider() returns None before the NoOp check.
- Confirm your provider is not a NoOpMeterProvider via `isinstance(metrics.get_meter_provider(), NoOpMeterProvider)` returns False after setup.
Example fix
# before - metrics enabled, provider never set
from redis.observability import get_observability_instance, OTelConfig
otel = get_observability_instance()
otel.init(OTelConfig(enable_metrics=True)) # first command -> providers.py:90 RuntimeError
# after - set global provider first
from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
reader = PeriodicExportingMetricReader(
exporter=OTLPMetricExporter(endpoint='http://localhost:4318/v1/metrics'),
export_interval_millis=10000,
)
metrics.set_meter_provider(MeterProvider(metric_readers=[reader]))
otel.init(OTelConfig(enable_metrics=True)) Defensive patterns
Strategy: validation
Validate before calling
from opentelemetry import metrics
from opentelemetry.metrics import NoOpMeterProvider
def real_provider_is_set():
return not isinstance(metrics.get_meter_provider(), NoOpMeterProvider)
# set the provider, then verify, before initializing redis-py observability
metrics.set_meter_provider(MeterProvider(metric_readers=[reader]))
assert real_provider_is_set(), 'global MeterProvider still NoOp'
otel.init(OTelConfig(enable_metrics=True)) Try / catch
try:
otel.init(OTelConfig(enable_metrics=True))
except RuntimeError as e:
if 'no global MeterProvider' in str(e):
logging.error('Set a global MeterProvider before enabling redis-py metrics')
else:
raise Prevention
- Always set metrics.set_meter_provider(...) before get_observability_instance().init(...).
- Centralize OTel SDK setup in a single startup function that runs before any Redis client issues commands.
- Assert isinstance(metrics.get_meter_provider(), NoOpMeterProvider) is False right after setup as a guard.
- If metrics are optional in some environments, pass OTelConfig(enabled_telemetry=[]) instead of enable_metrics=True.
When it happens
Trigger: Calling otel.init(OTelConfig(enable_metrics=True)) and then a Redis operation without ever having called metrics.set_meter_provider(MeterProvider(metric_readers=[...])) first. The check is `isinstance(self._meter_provider, NoOpMeterProvider)` — so any real provider set before init avoids this, while an unset global defaults to NoOp and trips it.
Common situations: App initializes redis-py observability at import time but defers OTel SDK setup to a later app hook that runs after the first Redis command; a framework integration (e.g. FastAPI/Django startup) sets the provider in a different lifecycle stage than the one that constructs the Redis client; test code that enables metrics without wiring a provider; ordering bug where set_meter_provider runs after otel.init's first get_meter_provider().
Related errors
- OpenTelemetry API is not installed. Install it with: pip…
- OpenTelemetry is not installed. Install it with: pip…
- Argument 'db' must be 0 or None in cluster mode
- Cache must implement CacheInterface
- Cannot disable maintenance notifications after enabling them
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/99546dc6b9f2d380.
Report an issue: GitHub.
Appendix: source
Thrown at redis/observability/providers.py:90
return None
# Lazy import - only import OTel when metrics are enabled
try:
from opentelemetry import metrics
from opentelemetry.metrics import NoOpMeterProvider
except ImportError:
raise ImportError(
"OpenTelemetry is not installed. Install it with:\n"
" pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http"
)
# Get the global MeterProvider
if self._meter_provider is None:
self._meter_provider = metrics.get_meter_provider()
# Check if it's a real provider (not NoOp)
if isinstance(self._meter_provider, NoOpMeterProvider):
raise RuntimeError(
"Metrics are enabled but no global MeterProvider is configured.\n"
"\n"
"Set up OpenTelemetry before initializing redis-py observability:\n"
"\n"
" from opentelemetry import metrics\n"
" from opentelemetry.sdk.metrics import MeterProvider\n"
" from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader\n"
" from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter\n"
"\n"
" # Create exporter\n"
" exporter = OTLPMetricExporter(\n"
" endpoint='http://localhost:4318/v1/metrics'\n"
" )\n"
"\n"
" # Create reader\n"
" reader = PeriodicExportingMetricReader(\n"
" exporter=exporter,\n"
" export_interval_millis=10000\n"View on GitHub (pinned to 6a6b581b48)