{"id":"3883771275bd25f7","repo":"go-redis/redis","slug":"failed-to-create-operation-duration-histogram-w","errorCode":null,"errorMessage":"failed to create operation duration histogram: %w","messagePattern":"failed to create operation duration histogram: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extra/redisotel-native/redisotel.go","lineNumber":194,"sourceCode":"\t}\n}\n\n// createRecorder creates a metricsRecorder with all instruments based on config.\nfunc (o *ObservabilityInstance) createRecorder(meter metric.Meter, cfg config) (*metricsRecorder, error) {\n\tvar err error\n\n\tvar operationDuration metric.Float64Histogram\n\tif cfg.isMetricGroupEnabled(MetricGroupCommand) {\n\t\tvar operationDurationOpts []metric.Float64HistogramOption\n\t\tif cfg.histAggregation == HistogramAggregationExplicitBucket {\n\t\t\toperationDurationOpts = append(operationDurationOpts,\n\t\t\t\tmetric.WithExplicitBucketBoundaries(cfg.bucketsOperationDuration...),\n\t\t\t)\n\t\t}\n\t\tvar operationDurationConv dbconv.ClientOperationDuration\n\t\toperationDurationConv, err = dbconv.NewClientOperationDuration(meter, operationDurationOpts...)\n\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}","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/extra/redisotel-native/redisotel.go#L176-L212","documentation":"Returned by createRecorder (redisotel.go:194) when dbconv.NewClientOperationDuration fails to create the 'db.client.operation.duration' Float64Histogram. Only checked when the MetricGroupCommand group is enabled. The wrapped error comes from the OTel SDK's meter.Float64Histogram call.","triggerScenarios":"Calling Init with MetricGroups including MetricGroupFlagCommand, and the OTel SDK rejects the histogram creation (duplicate name with conflicting metadata, invalid name, or a broken MeterProvider).","commonSituations":"Another instrumentation library already registered 'db.client.operation.duration' with different unit or description; the global MeterProvider is the default no-op but an incompatible SDK version is mixed in; custom bucket boundaries in cfg.BucketsOperationDuration are malformed.","solutions":["Search for other code registering 'db.client.operation.duration' and reconcile unit/description metadata","Verify the MeterProvider is from a compatible OTel SDK version","Check that cfg.BucketsOperationDuration contains valid float64 boundary values when HistogramAggregation is ExplicitBucket"],"exampleFix":"// before - conflicting 'db.client.operation.duration' from another lib\nhist, _ := meter.Float64Histogram(\"db.client.operation.duration\",\n    metric.WithUnit(\"ms\")) // conflicts with semconv unit \"s\"\n\n// after - use the same unit as redisotel semconv (seconds)\nhist, _ := meter.Float64Histogram(\"db.client.operation.duration\",\n    metric.WithUnit(\"s\"))","handlingStrategy":"try-catch","validationCode":"// Validate bucket boundaries are monotonically increasing before Init\nfor i := 1; i < len(cfg.BucketsOperationDuration); i++ {\n    if cfg.BucketsOperationDuration[i] <= cfg.BucketsOperationDuration[i-1] {\n        return fmt.Errorf(\"invalid bucket boundaries\")\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := obs.Init(cfg); err != nil {\n    if strings.Contains(err.Error(), \"operation duration histogram\") {\n        log.Error(\"conflict on 'db.client.operation.duration'; reconcile metadata across OTel integrations\")\n    }\n}","preventionTips":["Ensure no other library registers 'db.client.operation.duration' with conflicting unit or description","Validate custom histogram bucket boundaries are monotonically increasing","Use a compatible OTel SDK version"],"tags":["otel","redisotel-native","metrics","histogram","operation-duration"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}