grpc/grpc-go · error
failed to register observability views: %v
Error message
failed to register observability views: %v
What it means
Returned when view.Register(defaultViews...) fails. OpenCensus's view.Register fails if any of the supplied views are already registered (duplicate name). This typically indicates Start() was invoked twice, or another package already registered the gRPC OpenCensus views.
Source
Thrown at gcp/observability/opencensus.go:146
return nil
}
var err error
exporter, err = newExporter(config)
if err != nil {
return err
}
var to opencensus.TraceOptions
if config.CloudTrace != nil {
to.TS = trace.ProbabilitySampler(config.CloudTrace.SamplingRate)
trace.RegisterExporter(exporter.(trace.Exporter))
logger.Infof("Start collecting and exporting trace spans with global_trace_sampling_rate=%.2f", config.CloudTrace.SamplingRate)
}
if config.CloudMonitoring != nil {
if err := view.Register(defaultViews...); err != nil {
return fmt.Errorf("failed to register observability views: %v", err)
}
view.SetReportingPeriod(defaultMetricsReportingInterval)
view.RegisterExporter(exporter.(view.Exporter))
logger.Infof("Start collecting and exporting metrics")
}
internal.AddGlobalServerOptions.(func(opt ...grpc.ServerOption))(opencensus.ServerOption(to))
internal.AddGlobalDialOptions.(func(opt ...grpc.DialOption))(opencensus.DialOption(to))
logger.Infof("Enabled OpenCensus StatsHandlers for clients and servers")
return nil
}
// stopOpenCensus flushes the exporter's and cleans up globals across all
// packages if exporter was created.
func stopOpenCensus() {
if exporter != nil {
internal.ClearGlobalDialOptions()View on GitHub (pinned to 03255a9237)
Solutions
- Call observability.Start() exactly once at process startup.
- Remove duplicate opencensus.RegisterViews/stats.Register calls for the gRPC default views.
- Move Start() to TestMain or a sync.Once guard so repeated invocations are no-ops.
- Call view.Unregister(defaultViews...) before re-registering if you must rebuild.
Example fix
// before
var startOnce sync.Once
// ...
func setup() {
observability.Start(ctx) // called per request -> duplicate registration
}
// after
var startOnce sync.Once
func setup() {
startOnce.Do(func() {
if err := observability.Start(ctx); err != nil { log.Fatal(err) }
})
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure Start() runs once per process.
var startOnce sync.Once
var startErr error
func EnsureObservability(ctx context.Context) {
startOnce.Do(func() { startErr = observability.Start(ctx) })
} Try / catch
if err := observability.Start(ctx); err != nil {
if strings.Contains(err.Error(), "failed to register observability views") {
// Duplicate registration: views already registered by another init; safe to continue.
log.Printf("views already registered: %v", err)
}
} Prevention
- Never call Start() more than once; wrap in sync.Once.
- Remove duplicate opencensus view registration elsewhere in the binary.
- In tests, register/unregister views in TestMain, not per-case.
When it happens
Trigger: Calling observability.Start() more than once in one process; importing both this observability package and a separate call to opencensus.RegisterViews/stats.Register that registers the same gRPC views; running the observability binary inside a test harness that already instrumented views.
Common situations: Mixing the gRPC Observability plugin with hand-rolled OpenCensus setup; init() in a helper package that also registers gRPC views; tests that run Start() per test case instead of once per process.
Related errors
- failed to instrument OpenCensus: %v
- cannot have a leading slash
- / must come in between service and method, only one /
- method name must be non empty
- cannot have exclude and a '*' wildcard
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/d48f4e710a54632b.
Report an issue: GitHub.