{"record":{"id":"0281ee713ae7d95b","repo":"redis/go-redis","slug":"failed-to-create-client-errors-metric-w","errorCode":null,"errorMessage":"failed to create client errors metric: %w","messagePattern":"failed to create client errors metric: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extra/redisotel-native/redisotel.go","lineNumber":255,"sourceCode":"\t\t\tMetricConnectionHandoff,\n\t\t\tmetric.WithDescription(\"Connections that have been handed off to another node (e.g after a MOVING notification)\"),\n\t\t)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create connection handoff metric: %w\", err)\n\t\t}\n\t}\n\n\tvar clientErrors metric.Int64Counter\n\tvar maintenanceNotifications metric.Int64Counter\n\n\tif cfg.isMetricGroupEnabled(MetricGroupResiliency) {\n\t\tclientErrors, err = meter.Int64Counter(\n\t\t\tMetricClientErrors,\n\t\t\tmetric.WithDescription(\"Number of errors handled by the Redis client\"),\n\t\t\tmetric.WithUnit(\"{error}\"),\n\t\t)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create client errors metric: %w\", err)\n\t\t}\n\n\t\tmaintenanceNotifications, err = meter.Int64Counter(\n\t\t\tMetricMaintenanceNotifications,\n\t\t\tmetric.WithDescription(\"Number of maintenance notifications received\"),\n\t\t\tmetric.WithUnit(\"{notification}\"),\n\t\t)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create maintenance notifications metric: %w\", err)\n\t\t}\n\t}\n\n\tvar connectionWaitTime metric.Float64Histogram\n\tvar connectionClosed metric.Int64Counter\n\tvar connectionPendingReqs metric.Int64UpDownCounter // OTel semconv: UpDownCounter\n\n\tif cfg.isMetricGroupEnabled(MetricGroupConnectionAdvanced) {\n\t\tvar connectionWaitTimeOpts []metric.Float64HistogramOption","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/extra/redisotel-native/redisotel.go#L237-L273","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nerr := obs.Init(&redisotel.Config{Enabled: true}) // MetricGroupFlagResiliency set, provider stopped\n// after\n// start provider first, then init\nprovider := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader))\nerr := obs.Init(&redisotel.Config{Enabled: true, MetricGroups: redisotel.MetricGroupFlagResiliency, MeterProvider: provider})","handlingStrategy":"try-catch","validationCode":"// ensure provider active\nif err := provider.ForceFlush(context.Background()); err != nil {\n    return fmt.Errorf(\"meter provider not healthy: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := obs.Init(cfg); err != nil {\n    if strings.Contains(err.Error(), \"client errors metric\") {\n        cfg.MetricGroups &^= redisotel.MetricGroupFlagResiliency\n        err = obs.Init(cfg) // retry without resiliency group\n    }\n}","preventionTips":["Verify provider health (ForceFlush) before Init","Avoid metric name collisions between instrumentation packages","Log Init failures","Upgrade otel modules together"],"tags":["opentelemetry","metrics","resiliency","go"],"backgroundTag":"otel-instrument-creation-failed","analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}