googleapis/mcp-toolbox · error

error in User Agent retrieval: %s

Error message

error in User Agent retrieval: %s

What it means

Serverless Spark source Initialize first extracts a user agent string from the incoming context via util.UserAgentFromContext. If the context does not carry a valid user agent (missing or malformed), initialization fails before creating any Dataproc clients. This is a context/metadata plumbing error, not a network error.

Source

Thrown at internal/sources/serverlessspark/serverlessspark.go:70

	}
	return actual, nil
}

type Config struct {
	Name     string `yaml:"name" validate:"required"`
	Type     string `yaml:"type" validate:"required"`
	Project  string `yaml:"project" validate:"required"`
	Location string `yaml:"location" validate:"required"`
}

func (r Config) SourceConfigType() string {
	return SourceType
}

func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
	ua, err := util.UserAgentFromContext(ctx)
	if err != nil {
		return nil, fmt.Errorf("error in User Agent retrieval: %s", err)
	}
	endpoint := fmt.Sprintf("%s-dataproc.googleapis.com:443", r.Location)
	batchClient, err := dataproc.NewBatchControllerClient(ctx, option.WithEndpoint(endpoint), option.WithUserAgent(ua))
	if err != nil {
		return nil, fmt.Errorf("failed to create dataproc batch client: %w", err)
	}
	sessionTemplateClient, err := dataproc.NewSessionTemplateControllerClient(ctx, option.WithEndpoint(endpoint), option.WithUserAgent(ua))
	if err != nil {
		batchClient.Close()
		return nil, fmt.Errorf("failed to create dataproc session template client: %w", err)
	}
	opsClient, err := longrunning.NewOperationsClient(ctx, option.WithEndpoint(endpoint), option.WithUserAgent(ua))
	if err != nil {
		batchClient.Close()
		sessionTemplateClient.Close()
		return nil, fmt.Errorf("failed to create longrunning client: %w", err)
	}
	sessionClient, err := dataproc.NewSessionControllerClient(ctx, option.WithEndpoint(endpoint), option.WithUserAgent(ua))

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Create the source through the normal toolbox server request path so the user agent metadata is injected into the context.
  2. If calling Initialize directly (tests/custom code), add the expected user agent to the context the way the server does (check util.UserAgentFromContext for the metadata key/format).
  3. Ensure clients send a non-empty, well-formed User-Agent header.
  4. Check the toolbox version for changes in the user agent contract between client and server.

Example fix

// before (direct init in test)
src, err := cfg.Initialize(ctx, tracer) // ctx has no user agent
// after
ctx = metadata.AppendToOutgoingContext(ctx, "user-agent", "opencode/1.0")
src, err := cfg.Initialize(ctx, tracer)
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the user agent is present in the outgoing context before source init
ua, err := util.UserAgentFromContext(ctx)
if err != nil || ua == "" {
    return fmt.Errorf("user agent missing from context: %w", err)
}

Try / catch

src, err := cfg.Initialize(ctx, tracer)
if err != nil {
    if strings.Contains(err.Error(), "User Agent") {
        // re-init with a context carrying the user agent metadata
        ctx = util.NewContextWithUserAgent(ctx, "my-client/1.0")
        src, err = cfg.Initialize(ctx, tracer)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Config.Initialize runs util.UserAgentFromContext(ctx); the error branch fires when the context lacks the user agent header/metadata that the utility requires, or the metadata value fails the utility's parsing/format checks.

Common situations: Invoking the source programmatically with a bare context.Context instead of going through the toolbox server, which injects the user agent; constructing the source in unit tests without the expected metadata key; a client sending an empty or malformed User-Agent header.

Related errors


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