go-redis/redis · error
failed to create metrics recorder: %w
Error message
failed to create metrics recorder: %w
What it means
Returned by ObservabilityInstance.Init (redisotel.go:100) when createRecorder fails to build the metricsRecorder. This is the umbrella error wrapping the specific instrument-creation failure that occurred inside createRecorder (one of errors 127-138). It means the entire redisotel-native instrumentation setup failed and no metrics will be collected.
Source
Thrown at extra/redisotel-native/redisotel.go:100
if !cfg.Enabled {
return nil
}
// Get meter provider (use global if not provided)
meterProvider := cfg.MeterProvider
if meterProvider == nil {
meterProvider = otel.GetMeterProvider()
}
meter := meterProvider.Meter(
"github.com/redis/go-redis",
metric.WithInstrumentationVersion(redis.Version()),
)
internalCfg := o.configToInternal(cfg)
recorder, err := o.createRecorder(meter, internalCfg)
if err != nil {
return fmt.Errorf("failed to create metrics recorder: %w", err)
}
o.recorder = recorder
o.initialized = true
redis.SetOTelRecorder(recorder)
return nil
}
// IsEnabled returns true if observability is initialized and enabled.
func (o *ObservabilityInstance) IsEnabled() bool {
o.mu.RLock()
defer o.mu.RUnlock()
return o.initialized && o.config != nil && o.config.Enabled
}
// Shutdown cleans up resources and flushes any pending metrics.
// This should be called at application shutdown.View on GitHub (pinned to 36d97525cd)
Solutions
- Inspect the wrapped error via errors.Unwrap to find which specific instrument failed (errors 127-138)
- Fix the root cause indicated by the wrapped error (most commonly a duplicate instrument name conflict from another OTel integration)
- Ensure the MeterProvider passed via cfg.MeterProvider (or the global provider) is valid and not shut down
Example fix
// before
if err := obs.Init(cfg); err != nil {
panic(err)
}
// after
if err := obs.Init(cfg); err != nil {
log.Errorf("redisotel init failed: %v", err)
if unwrapped := errors.Unwrap(err); unwrapped != nil {
log.Errorf("root cause: %v", unwrapped)
}
// continue without metrics, or fix the conflict and retry
} Defensive patterns
Strategy: try-catch
Validate before calling
// Verify MeterProvider is non-nil and functional before calling Init
if cfg.MeterProvider == nil {
cfg.MeterProvider = otel.GetMeterProvider()
} Try / catch
if err := obs.Init(cfg); err != nil {
log.Errorf("redisotel init failed: %v", err)
if root := errors.Unwrap(err); root != nil {
log.Errorf("root cause: %v", root)
}
// degrade gracefully without metrics
} Prevention
- Inspect the wrapped error to identify which specific instrument creation failed
- Avoid registering OTel instruments with the same name but conflicting metadata across libraries
- Call Init exactly once at startup; call Shutdown before re-initializing
When it happens
Trigger: Calling GetObservabilityInstance().Init(cfg) where at least one enabled metric group triggers an OTel SDK instrument-creation error inside createRecorder.
Common situations: Another part of the application already registered an instrument with the same name but conflicting metadata (unit, description, or instrument type); the MeterProvider is nil, shut down, or broken; invalid custom bucket boundaries in HistogramAggregation configuration.
Related errors
- failed to create operation duration histogram: %w
- failed to create connection count metric: %w
- failed to create connection create time histogram: %w
- failed to create connection relaxed timeout metric: %w
- failed to create connection handoff metric: %w
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/299a311ac8c3077e.json.
Report an issue: GitHub.