redis/go-redis · error
failed to create client errors metric: %w
Error message
failed to create client errors metric: %w
What it means
Returned by createRecorder when meter.Int64Counter fails to create the redis.client.errors counter, which counts errors handled by the Redis client (resiliency metric group). Init fails with 'failed to create metrics recorder' and no resiliency metrics are collected. The MeterProvider rejected instrument creation.
Source
Thrown at extra/redisotel-native/redisotel.go:255
MetricConnectionHandoff,
metric.WithDescription("Connections that have been handed off to another node (e.g after a MOVING notification)"),
)
if err != nil {
return nil, fmt.Errorf("failed to create connection handoff metric: %w", err)
}
}
var clientErrors metric.Int64Counter
var maintenanceNotifications metric.Int64Counter
if cfg.isMetricGroupEnabled(MetricGroupResiliency) {
clientErrors, err = meter.Int64Counter(
MetricClientErrors,
metric.WithDescription("Number of errors handled by the Redis client"),
metric.WithUnit("{error}"),
)
if err != nil {
return nil, fmt.Errorf("failed to create client errors metric: %w", err)
}
maintenanceNotifications, err = meter.Int64Counter(
MetricMaintenanceNotifications,
metric.WithDescription("Number of maintenance notifications received"),
metric.WithUnit("{notification}"),
)
if err != nil {
return nil, fmt.Errorf("failed to create maintenance notifications metric: %w", err)
}
}
var connectionWaitTime metric.Float64Histogram
var connectionClosed metric.Int64Counter
var connectionPendingReqs metric.Int64UpDownCounter // OTel semconv: UpDownCounter
if cfg.isMetricGroupEnabled(MetricGroupConnectionAdvanced) {
var connectionWaitTimeOpts []metric.Float64HistogramOptionView on GitHub (pinned to c5cad058c7)
Solutions
- Guarantee a live MeterProvider before Init; do not call provider.Shutdown() earlier in startup
- Check for another component already registering redis.client.errors and remove the duplicate
- Read the wrapped error (errors.Unwrap) and otel global error-handler logs to pinpoint the SDK rejection
- Keep otel module versions aligned across go.mod files
- Temporarily disable MetricGroupFlagResiliency to confirm group-specific failure
Example fix
// before
err := obs.Init(&redisotel.Config{Enabled: true}) // MetricGroupFlagResiliency set, provider stopped
// after
// start provider first, then init
provider := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader))
err := obs.Init(&redisotel.Config{Enabled: true, MetricGroups: redisotel.MetricGroupFlagResiliency, MeterProvider: provider}) Defensive patterns
Strategy: try-catch
Validate before calling
// ensure provider active
if err := provider.ForceFlush(context.Background()); err != nil {
return fmt.Errorf("meter provider not healthy: %w", err)
} Try / catch
if err := obs.Init(cfg); err != nil {
if strings.Contains(err.Error(), "client errors metric") {
cfg.MetricGroups &^= redisotel.MetricGroupFlagResiliency
err = obs.Init(cfg) // retry without resiliency group
}
} Prevention
- Verify provider health (ForceFlush) before Init
- Avoid metric name collisions between instrumentation packages
- Log Init failures
- Upgrade otel modules together
When it happens
Trigger: Init with MetricGroupFlagResiliency enabled while the MeterProvider is shut down or misconfigured; duplicate instrument registration of redis.client.errors with a conflicting unit ({error}) in providers that enforce uniqueness.
Common situations: Applications wiring multiple observability shims (extra/redisprometheus plus redisotel-native) that register overlapping metric names; providers swapped or stopped during test cleanup before Init runs.
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 redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/0281ee713ae7d95b.
Report an issue: GitHub.