{"record":{"id":"145ad67006051b79","repo":"redis/go-redis","slug":"failed-to-create-metrics-recorder-w","errorCode":null,"errorMessage":"failed to create metrics recorder: %w","messagePattern":"failed to create metrics recorder: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extra/redisotel-native/redisotel.go","lineNumber":100,"sourceCode":"\tif !cfg.Enabled {\n\t\treturn nil\n\t}\n\n\t// Get meter provider (use global if not provided)\n\tmeterProvider := cfg.MeterProvider\n\tif meterProvider == nil {\n\t\tmeterProvider = otel.GetMeterProvider()\n\t}\n\n\tmeter := meterProvider.Meter(\n\t\t\"github.com/redis/go-redis\",\n\t\tmetric.WithInstrumentationVersion(redis.Version()),\n\t)\n\n\tinternalCfg := o.configToInternal(cfg)\n\trecorder, err := o.createRecorder(meter, internalCfg)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create metrics recorder: %w\", err)\n\t}\n\n\to.recorder = recorder\n\to.initialized = true\n\tredis.SetOTelRecorder(recorder)\n\n\treturn nil\n}\n\n// IsEnabled returns true if observability is initialized and enabled.\nfunc (o *ObservabilityInstance) IsEnabled() bool {\n\to.mu.RLock()\n\tdefer o.mu.RUnlock()\n\treturn o.initialized && o.config != nil && o.config.Enabled\n}\n\n// Shutdown cleans up resources and flushes any pending metrics.\n// This should be called at application shutdown.","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/extra/redisotel-native/redisotel.go#L82-L118","documentation":"redisotel-native's Init sets up OpenTelemetry metrics instrumentation and creates a metrics recorder from the configured meter. If recorder creation fails (bad metric config, meter provider misconfigured), Init wraps and returns the underlying error via %w. The instrumentation is therefore not enabled and redis.SetOTelRecorder is never called.","triggerScenarios":"Calling Init (public) with an InstrumentationMetrics config whose options make createRecorder fail — e.g. an invalid meter provider, closed provider, or conflicting instrument configuration — at redisotel.go:~100.","commonSituations":"Meter provider not registered or shut down before Init; invalid metrics options in redisotel.InstrumentMetrics config; duplicate instrument creation with the same name/options; missing OpenTelemetry SDK setup in the app.","solutions":["Unwrap the returned error (%w preserves it) to see the root cause from createRecorder.","Initialize and register the global/system meter provider (otel.SetMeterProvider) before calling Init.","Review the InstrumentationMetrics options for invalid values and fix them.","Ensure Init is called only once per client set of options and the provider is not shutdown mid-run."],"exampleFix":"// before: no meter provider registered\nerr := instrumentor.Init(ctx, cfg) // failed to create metrics recorder: no meter provider\n\n// after: set up the provider first\nprovider := sdkmetric.NewMeterProvider()\notel.SetMeterProvider(provider)\nerr := instrumentor.Init(ctx, cfg)","handlingStrategy":"try-catch","validationCode":"// ensure a meter provider exists before Init\nif otel.GetMeterProvider() == otel.GetMeterProvider() &&\n   os.Getenv(\"OTEL_SDK_DISABLED\") != \"true\" {\n    // proceed; otherwise configure sdkmetric provider first\n}","typeGuard":null,"tryCatchPattern":"if err := instrumentor.Init(ctx, cfg); err != nil {\n    var root error\n    errors.As(err, &root) // %w chain preserves createRecorder cause\n    log.Printf(\"otel init failed: %v\", root) // use internal.Logger in lib code\n    // continue without instrumentation\n}","preventionTips":["Register the OTel meter provider before calling Init","Do not shut down the provider while the client is running","Validate InstrumentationMetrics options before Init","Call Init once during application bootstrap","Check errors with errors.As/Unwrap to reach the root cause"],"tags":["opentelemetry","metrics","initialization","redisotel"],"backgroundTag":"otel-initialization-failed","analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}