googleapis/mcp-toolbox · error

error getting user agent from context: %w

Error message

error getting user agent from context: %w

What it means

Thrown by the Elasticsearch source's Config.Initialize when util.UserAgentFromContext(ctx) fails, i.e. the incoming context does not carry the user agent value the toolbox requires for instrumentation. Initialize wraps the error with %w and aborts source creation, so the Elasticsearch client is never constructed.

Source

Thrown at internal/sources/elasticsearch/elasticsearch.go:94

// tracerProviderAdapter adapts a Tracer to implement the TracerProvider interface
type tracerProviderAdapter struct {
	trace.TracerProvider
	tracer trace.Tracer
}

// Tracer implements the TracerProvider interface
func (t *tracerProviderAdapter) Tracer(name string, options ...trace.TracerOption) trace.Tracer {
	return t.tracer
}

// Initialize creates a new Elasticsearch Source instance.
func (c Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
	tracerProvider := &tracerProviderAdapter{tracer: tracer}

	ua, err := util.UserAgentFromContext(ctx)
	if err != nil {
		return nil, fmt.Errorf("error getting user agent from context: %w", err)
	}

	// Create a new Elasticsearch client with the provided configuration
	cfg := elasticsearch.Config{
		Addresses:       c.Addresses,
		Instrumentation: elasticsearch.NewOpenTelemetryInstrumentation(tracerProvider, false),
		Header:          http.Header{"User-Agent": []string{ua + " go-elasticsearch/" + elasticsearch.Version}},
	}

	// Client need either username and password or an API key
	if c.Username != "" && c.Password != "" {
		cfg.Username = c.Username
		cfg.Password = c.Password
	} else if c.APIKey != "" {
		// API key will be set below
		cfg.APIKey = c.APIKey
	} else {
		// If neither username/password nor API key is provided, we throw an error

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Let the toolbox server initialize the source from its normal request lifecycle so the user agent is present in the context.
  2. In tests or custom code, add the user agent to the context the way the server does (use the util package's context helpers) before calling Initialize.
  3. Upgrade the toolbox if you believe a valid user-agent context is being dropped — check util.UserAgentFromContext expectations.

Example fix

// before
src, err := cfg.Initialize(context.Background(), tracer)
// after
ctx := util.ContextWithUserAgent(context.Background(), "mcp-toolbox/1.0")
src, err := cfg.Initialize(ctx, tracer)
Defensive patterns

Strategy: validation

Validate before calling

if ua, ok := ctx.Value(util.UserAgentKey{}).(string); !ok || ua == "" {
    return errors.New("user agent missing from context; use the server-provided request context")
}

Type guard

func hasUserAgent(ctx context.Context) bool {
    ua, err := util.UserAgentFromContext(ctx)
    return err == nil && ua != ""
}

Try / catch

src, err := cfg.Initialize(ctx, tracer)
if err != nil {
    if strings.Contains(err.Error(), "error getting user agent from context") {
        return nil, fmt.Errorf("initialize the elasticsearch source through the toolbox server (context must carry a user agent): %w", err)
    }
    return nil, err
}

Prevention

When it happens

Trigger: Config.Initialize is called with a context that lacks the user agent value (util.UserAgentFromContext returns an error) — usually when a source is initialized programmatically with a bare context.Background() instead of the server-provided request context.

Common situations: Custom code or tests constructing the Elasticsearch source directly with context.Background()/context.TODO(), bypassing the toolbox server which normally injects the user agent into the request context.

Related errors


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