googleapis/mcp-toolbox · error

useClientOAuth cannot be used with impersonateServiceAccount

Error message

useClientOAuth cannot be used with impersonateServiceAccount

What it means

Initialize rejects using useClientOAuth together with impersonateServiceAccount. Client OAuth means the end user's credentials are used per invocation, while impersonation means the service account's identity is used server-side; the two auth strategies are mutually exclusive and cannot be combined.

Source

Thrown at internal/sources/bigquery/bigquery.go:174

		if *r.ReadOnly != isReadOnlyMode {
			return nil, fmt.Errorf("conflicting source configuration: readOnly is %v, but writeMode is %q", *r.ReadOnly, r.WriteMode)
		}
	}

	if r.MaxQueryResultRows == 0 {
		r.MaxQueryResultRows = 50
	}

	if r.WriteMode == WriteModeProtected && strings.ToLower(r.UseClientOAuth) != "false" && r.UseClientOAuth != "" {
		// The protected mode only allows write operations to the session's temporary datasets.
		// when using client OAuth, a new session is created every
		// time a BigQuery tool is invoked. Therefore, no session data can
		// be preserved as needed by the protected mode.
		return nil, fmt.Errorf("writeMode 'protected' cannot be used with useClientOAuth enabled")
	}

	if strings.ToLower(r.UseClientOAuth) != "false" && r.UseClientOAuth != "" && r.ImpersonateServiceAccount != "" {
		return nil, fmt.Errorf("useClientOAuth cannot be used with impersonateServiceAccount")
	}

	endpoint := NormalizeEndpoint(r.APIEndpoint)

	var client *bigqueryapi.Client
	var restService *bigqueryrestapi.Service
	var tokenSource oauth2.TokenSource
	var clientCreator BigqueryClientCreator
	var err error

	s := &Source{
		Config:              r,
		Client:              client,
		RestService:         restService,
		TokenSource:         tokenSource,
		ClientCreator:       clientCreator,
		AuthTokenHeaderName: "Authorization",
	}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Remove the impersonateServiceAccount field if client OAuth is the intended auth path.
  2. Set useClientOAuth: "false" if impersonation is the intended auth path.
  3. Split into two separate sources/configs if both auth modes are needed for different users.

Example fix

// before
useClientOAuth: "true"
impersonateServiceAccount: sa@project.iam.gserviceaccount.com
// after
useClientOAuth: "true"
Defensive patterns

Strategy: validation

Validate before calling

func validateAuthMode(useClientOAuth, impersonate string) error {
	clientOAuth := useClientOAuth != "" && strings.ToLower(useClientOAuth) != "false"
	if clientOAuth && impersonate != "" {
		return fmt.Errorf("useClientOAuth and impersonateServiceAccount are mutually exclusive")
	}
	return nil
}

Try / catch

src, err := sourceRegistry.Initialize(ctx, cfg)
if err != nil {
	if strings.Contains(err.Error(), "impersonateServiceAccount") {
		return fmt.Errorf("remove one auth strategy from config: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: BigQuery source config where useClientOAuth is enabled (not "false" and not empty) and impersonateServiceAccount is set to a non-empty service account email.

Common situations: Adding impersonation for least-privilege access on a source that already enables client OAuth; template configs that include both fields unconditionally.

Related errors


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