{"record":{"id":"29363e0ff3fe7a28","repo":"redis/go-redis","slug":"failed-to-create-connection-count-metric-w","errorCode":null,"errorMessage":"failed to create connection count metric: %w","messagePattern":"failed to create connection count metric: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extra/redisotel-native/redisotel.go","lineNumber":211,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create operation duration histogram: %w\", err)\n\t\t}\n\t\toperationDuration = operationDurationConv.Inst()\n\t}\n\n\tvar connectionCount metric.Int64UpDownCounter // OTel semconv: UpDownCounter\n\tvar connectionCreateTime metric.Float64Histogram\n\tvar connectionRelaxedTimeout metric.Int64UpDownCounter\n\tvar connectionHandoff metric.Int64Counter\n\n\tif cfg.isMetricGroupEnabled(MetricGroupConnectionBasic) {\n\t\tconnectionCount, err = meter.Int64UpDownCounter(\n\t\t\tdbconv.ClientConnectionCount{}.Name(),\n\t\t\tmetric.WithDescription(dbconv.ClientConnectionCount{}.Description()),\n\t\t\tmetric.WithUnit(dbconv.ClientConnectionCount{}.Unit()),\n\t\t)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create connection count metric: %w\", err)\n\t\t}\n\n\t\tvar connectionCreateTimeOpts []metric.Float64HistogramOption\n\t\tif cfg.histAggregation == HistogramAggregationExplicitBucket {\n\t\t\tconnectionCreateTimeOpts = append(connectionCreateTimeOpts,\n\t\t\t\tmetric.WithExplicitBucketBoundaries(cfg.bucketsConnectionCreateTime...),\n\t\t\t)\n\t\t}\n\t\tvar connectionCreateTimeConv dbconv.ClientConnectionCreateTime\n\t\tconnectionCreateTimeConv, err = dbconv.NewClientConnectionCreateTime(meter, connectionCreateTimeOpts...)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create connection create time histogram: %w\", err)\n\t\t}\n\t\tconnectionCreateTime = connectionCreateTimeConv.Inst()\n\n\t\tconnectionRelaxedTimeout, err = meter.Int64UpDownCounter(\n\t\t\tMetricConnectionRelaxedTimeout,\n\t\t\tmetric.WithDescription(\"How many times the connection timeout has been increased/decreased (after a server maintenance notification)\"),","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/extra/redisotel-native/redisotel.go#L193-L229","documentation":"Returned by createRecorder when meter.Int64UpDownCounter fails to create the db.client.connection.count UpDownCounter (dbconv.ClientConnectionCount). Init aborts with 'failed to create metrics recorder', leaving observability uninitialized. This only happens when the underlying MeterProvider errors on instrument registration.","triggerScenarios":"Calling Init with MetricGroupFlagConnectionBasic enabled while the MeterProvider is shut down, is the global no-op provider with a failing error handler path, or a custom provider that rejects the instrument name/unit/description from dbconv semconv v1.38.0.","commonSituations":"Provider shutdown ordering bugs in test suites; using an unsupported or stub MeterProvider; version mismatch between go-redis redisotel-native's dbconv package and the installed otel/metric SDK.","solutions":["Provide a working MeterProvider in cfg.MeterProvider or set a global one via otel.SetMeterProvider before Init","Verify the provider was not Shutdown earlier in the process","Inspect the wrapped error via errors.As/Unwrap and the otel global error handler for the root cause","Align go.opentelemetry.io/otel versions across modules (go mod tidy / go mod vendor) so dbconv and the SDK agree on semconv","Temporarily disable MetricGroupFlagConnectionBasic to isolate which instrument fails"],"exampleFix":"// before\notel.SetMeterProvider(noopProvider)\n_ = obs.Init(&redisotel.Config{Enabled: true})\n// after\nsdk := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader))\n_ = obs.Init(&redisotel.Config{Enabled: true, MeterProvider: sdk})","handlingStrategy":"validation","validationCode":"if cfg.MetricGroups&redisotel.MetricGroupFlagConnectionBasic != 0 && cfg.MeterProvider == nil {\n    cfg.MeterProvider = otel.GetMeterProvider() // ensure a real SDK is set globally\n}","typeGuard":"if mp, ok := cfg.MeterProvider.(*sdkmetric.MeterProvider); !ok || mp == nil { /* configure SDK */ }","tryCatchPattern":"err := obs.Init(cfg)\nif err != nil && strings.Contains(err.Error(), \"connection count metric\") {\n    log.Printf(\"connection-count instrument failed: %v\", err)\n}","preventionTips":["Set a global MeterProvider via otel.SetMeterProvider early in main","Keep provider lifetime longer than redisotel lifetime","Check Init's error and log it","Avoid duplicate metric name registrations"],"tags":["opentelemetry","metrics","initialization","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"}