googleapis/mcp-toolbox · error

unable to create %s metric: %w

Error message

unable to create %s metric: %w

What it means

OpenTelemetry meter creation failed for the 'mcp.op.duration' histogram. CreateTelemetryInstrumentation registers several metrics; if the OTel meter API cannot instantiate this Float64Histogram (invalid instrument config or a meter provider in a failed state), it returns this wrapped error and the whole instrumentation setup fails.

Source

Thrown at internal/telemetry/instrumentation.go:60

	McpActiveSessions     metric.Int64UpDownCounter
	ToolExecutionDuration metric.Float64Histogram
}

func CreateTelemetryInstrumentation(versionString string) (*Instrumentation, error) {
	tracer := otel.Tracer(
		TracerName,
		trace.WithInstrumentationVersion(versionString),
	)

	meter := otel.Meter(MetricName, metric.WithInstrumentationVersion(versionString))

	mcpOperationDuration, err := meter.Float64Histogram(
		mcpOperationDurationName,
		metric.WithDescription("Duration of a single MCP JSON-RPC operation."),
		metric.WithUnit("s"),
	)
	if err != nil {
		return nil, fmt.Errorf("unable to create %s metric: %w", mcpOperationDurationName, err)
	}

	mcpSessionDuration, err := meter.Float64Histogram(
		mcpSessionDurationName,
		metric.WithDescription("Duration of an MCP session."),
		metric.WithUnit("s"),
	)
	if err != nil {
		return nil, fmt.Errorf("unable to create %s metric: %w", mcpSessionDurationName, err)
	}

	mcpActiveSessions, err := meter.Int64UpDownCounter(
		mcpActiveSessionsName,
		metric.WithDescription("Current count of active MCP sessions."),
		metric.WithUnit("{session}"),
	)
	if err != nil {
		return nil, fmt.Errorf("unable to create %s metric: %w", mcpActiveSessionsName, err)

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Ensure otel setup (SetupOTel) runs before CreateTelemetryInstrumentation and Shutdown has not been called first.
  2. Check the wrapped error; if it says the instrument is invalid, verify the metric name and unit are valid in your OTel SDK version.
  3. Avoid double-initializing telemetry; guard Setup with sync.Once or a flag.
  4. Pin compatible versions of go.opentelemetry.io/otel and the metrics SDK in go.mod.
  5. If telemetry is optional, log the error and continue with a no-op instrumentation instead of failing startup.
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure telemetry is initialized before instruments are created
if (!otelReady) { await setupOTel(); } // meter provider must be live

Try / catch

try {
  const instr = createTelemetryInstrumentation();
} catch (e) {
  if (String(e.message).includes("unable to create") && String(e.message).includes("metric")) {
    // log and fall back to no-op instrumentation
  }
}

Prevention

When it happens

Trigger: Calling Setup/CreateTelemetryInstrumentation where meter.Float64Histogram for the MCP operation duration name returns an error — most commonly when the backing OTel SDK meter provider was not initialized or was already shut down.

Common situations: Telemetry set up twice or after Shutdown was called, an OTel SDK version mismatch producing an invalid instrument configuration, or a custom MeterProvider failing to create instruments.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/6c97f8000c91ef7d. Report an issue: GitHub.