{"record":{"id":"0f515fc38273be64","repo":"redis/go-redis","slug":"failed-to-create-maintenance-notifications-metric","errorCode":null,"errorMessage":"failed to create maintenance notifications metric: %w","messagePattern":"failed to create maintenance notifications metric: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extra/redisotel-native/redisotel.go","lineNumber":264,"sourceCode":"\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\n\t\tif cfg.histAggregation == HistogramAggregationExplicitBucket {\n\t\t\tconnectionWaitTimeOpts = append(connectionWaitTimeOpts,\n\t\t\t\tmetric.WithExplicitBucketBoundaries(cfg.bucketsConnectionWaitTime...),\n\t\t\t)\n\t\t}\n\t\tvar connectionWaitTimeConv dbconv.ClientConnectionWaitTime\n\t\tconnectionWaitTimeConv, err = dbconv.NewClientConnectionWaitTime(meter, connectionWaitTimeOpts...)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create connection wait time histogram: %w\", err)","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/extra/redisotel-native/redisotel.go#L246-L282","documentation":"Returned by createRecorder when meter.Int64Counter fails to create the redis.client.maintenance.notifications counter, which counts RESP3 maintenance notifications received (MOVING, MIGRATING, etc.). Init aborts, leaving observability uninitialized. Cause is a MeterProvider that fails instrument registration.","triggerScenarios":"Init with MetricGroupFlagResiliency enabled against a shut-down/no-op/strict MeterProvider, or duplicate registration of the metric name with the conflicting unit {notification}.","commonSituations":"Deployments with maintenance-notification monitoring wired to a custom exporter whose provider rejects the instrument; test suites tearing down the metric SDK before the Redis clients init; otel version skew between dbconv-using modules.","solutions":["Start the metric SDK provider before redisotel Init and order shutdown as obs.Shutdown() then provider.Shutdown()","Verify no duplicate redis.client.maintenance.notifications registration exists","Unwrap the error to read the provider's specific failure and correct provider configuration","Run go mod tidy / consistent otel versions across modules","Drop MetricGroupFlagResiliency from Config.MetricGroups if the metric is unnecessary"],"exampleFix":"// before\nprovider.Shutdown(ctx)\nobs.Init(cfg)\n// after\nobs.Init(cfg)\n// later, at exit:\nobs.Shutdown()\nprovider.Shutdown(ctx)","handlingStrategy":"validation","validationCode":"if cfg.Enabled && meterProvider == nil {\n    return errors.New(\"redisotel: MeterProvider required when Enabled\")\n}","typeGuard":"if _, ok := meterProvider.(*sdkmetric.MeterProvider); !ok { /* install real SDK */ }","tryCatchPattern":"if err := obs.Init(cfg); err != nil {\n    otel.Handle(err)\n    log.Printf(\"maintenance-notification metrics unavailable: %v\", err)\n}","preventionTips":["Initialize the SDK provider before redisotel Init","Shutdown order: obs.Shutdown() then provider.Shutdown()","Check Init's error at startup","Avoid duplicate redis.client.maintenance.notifications registrations"],"tags":["opentelemetry","metrics","maintenance-notifications","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"}