{"record":{"id":"d48f4e710a54632b","repo":"grpc/grpc-go","slug":"failed-to-register-observability-views-v","errorCode":null,"errorMessage":"failed to register observability views: %v","messagePattern":"failed to register observability views: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gcp/observability/opencensus.go","lineNumber":146,"sourceCode":"\t\treturn nil\n\t}\n\n\tvar err error\n\texporter, err = newExporter(config)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar to opencensus.TraceOptions\n\tif config.CloudTrace != nil {\n\t\tto.TS = trace.ProbabilitySampler(config.CloudTrace.SamplingRate)\n\t\ttrace.RegisterExporter(exporter.(trace.Exporter))\n\t\tlogger.Infof(\"Start collecting and exporting trace spans with global_trace_sampling_rate=%.2f\", config.CloudTrace.SamplingRate)\n\t}\n\n\tif config.CloudMonitoring != nil {\n\t\tif err := view.Register(defaultViews...); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to register observability views: %v\", err)\n\t\t}\n\t\tview.SetReportingPeriod(defaultMetricsReportingInterval)\n\t\tview.RegisterExporter(exporter.(view.Exporter))\n\t\tlogger.Infof(\"Start collecting and exporting metrics\")\n\t}\n\n\tinternal.AddGlobalServerOptions.(func(opt ...grpc.ServerOption))(opencensus.ServerOption(to))\n\tinternal.AddGlobalDialOptions.(func(opt ...grpc.DialOption))(opencensus.DialOption(to))\n\tlogger.Infof(\"Enabled OpenCensus StatsHandlers for clients and servers\")\n\n\treturn nil\n}\n\n// stopOpenCensus flushes the exporter's and cleans up globals across all\n// packages if exporter was created.\nfunc stopOpenCensus() {\n\tif exporter != nil {\n\t\tinternal.ClearGlobalDialOptions()","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/gcp/observability/opencensus.go#L128-L164","documentation":"view.Register(defaultViews...) returned an error, which for OpenCensus means one of the default gRPC views is already registered. The default views are the opencensus client/server RPC views; the OpenCensus spec returns an error on duplicate name registration. Emitted at opencensus.go:146.","triggerScenarios":"Another part of the app (or another call path) already registered one of opencensus.ClientStartedRPCsView, ClientCompletedRPCsView, ServerStartedRPCsView, etc. Common when the app also uses go.opencensus.io/stats/opencensus directly, or when observability.Start is called twice.","commonSituations":"Mixing the grpc-gcp-observability plugin with direct opencensus view registration; calling Start more than once (e.g. in tests without resetting state); an unrelated library that registers the grpc default views; partial Start failure leaving views registered, then retry.","solutions":["Find the duplicate: grep for `view.Register` and any opencensus.ServerOption/opencensus.DialOption in your code.","Remove the conflicting registration so observability.Start owns these views, or skip cloud_monitoring in the config.","Call observability.Start exactly once per process; in tests call observability.End() and view.Unregister(defaultViews...) between cases.","If you need both instrumentations, register only non-overlapping views in your code."],"exampleFix":"// before\nview.Register(opencensus.ClientStartedRPCsView) // app code\nobservability.Start(ctx) // plugin re-registers -> error\n\n// after\n// remove the app-side registration; let the plugin own the grpc views\nobservability.Start(ctx)","handlingStrategy":"validation","validationCode":"// Detect duplicate registration before Start.\nfunc viewsAlreadyRegistered() error {\n    for _, v := range defaultViews {\n        if got, err := view.Find(v.Name); err == nil && got != nil {\n            return fmt.Errorf(\"view %s already registered; unregister it or skip cloud_monitoring\", v.Name)\n        }\n    }\n    return nil\n}\n\nif err := viewsAlreadyRegistered(); err != nil { return err }","typeGuard":null,"tryCatchPattern":"if err := observability.Start(ctx); err != nil {\n    if strings.Contains(err.Error(), \"failed to register observability views\") {\n        // duplicate registration — unregister the conflicting views and skip, or drop cloud_monitoring\n        view.Unregister(defaultViews...)\n        return err\n    }\n    return err\n}","preventionTips":["Let the observability plugin own the grpc opencensus default views; don't register them elsewhere.","Call Start exactly once per process.","In tests, view.Unregister(defaultViews...) and observability.End() between cases."],"tags":["observability","opencensus","metrics","duplicate-registration"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}