googleapis/mcp-toolbox · error

error creating service from OAuth access token: %w

Error message

error creating service from OAuth access token: %w

What it means

getService builds a Cloud Healthcare service client on the fly when the request carries a client-supplied OAuth access token (UseClientAuthorization()). It calls the configured ServiceCreator with the token string; if that constructor (which uses google oauth token sources / option.WithTokenSource) fails, the error is wrapped with this message. It indicates the OAuth token could not be turned into an authenticated healthcare service client.

Source

Thrown at internal/sources/cloudhealthcare/cloud_healthcare.go:298

	}
	if resp.StatusCode > 299 {
		return nil, fmt.Errorf("status %d %s: %s", resp.StatusCode, resp.Status, respBytes)
	}
	var jsonMap map[string]interface{}
	if err := json.Unmarshal(respBytes, &jsonMap); err != nil {
		return nil, fmt.Errorf("could not unmarshal response as json: %w", err)
	}
	return jsonMap, nil
}

func (s *Source) getService(tokenStr string) (*healthcare.Service, error) {
	svc := s.Service()
	var err error
	// Initialize new service if using user OAuth token
	if s.UseClientAuthorization() {
		svc, err = s.ServiceCreator()(tokenStr)
		if err != nil {
			return nil, fmt.Errorf("error creating service from OAuth access token: %w", err)
		}
	}
	return svc, nil
}

func isAlphanumeric(c byte) bool {
	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
}

func isValidAPIVersion(v string) bool {
	if len(v) < 2 || v[0] != 'v' {
		return false
	}
	// The character after 'v' must be a digit '1'-'9'
	if v[1] < '1' || v[1] > '9' {
		return false
	}
	for i := 2; i < len(v); i++ {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Verify the client is sending a valid, non-expired OAuth 2.0 access token in the Authorization header
  2. Refresh the token before the call (expired access tokens last ~1 hour)
  3. Ensure the token has the https://www.googleapis.com/auth/cloud-platform scope
  4. Check the source's configured service endpoint / universe domain is reachable
  5. If using ADC-based auth instead, drop the client Authorization header so the default token source is used

Example fix

// before: sending stale token
httpClient.Header.Set("Authorization", "Bearer " + staleToken)
// after
if token.Expiry.Before(time.Now().Add(5*time.Minute)) {
    token, err = tokenSource.Token()
    if err != nil { return err }
}
httpClient.Header.Set("Authorization", "Bearer " + token.AccessToken)
Defensive patterns

Strategy: validation

Validate before calling

function validateOAuthToken(tok) {
  if (!tok || tok.split('.').length < 2) return 'token malformed';
  try {
    const payload = JSON.parse(atob(tok.split('.')[1].replace(/-/g, '+').replace(/_/g, '/')));
    if (payload.exp * 1000 < Date.now() + 60000) return 'token expired';
    if (!(payload.scope || '').includes('cloud-platform')) return 'missing cloud-platform scope';
    return null;
  } catch { return 'token not a JWT'; }
}

Type guard

function hasValidBearerAuth(headers) { const a = headers['authorization']; return typeof a === 'string' && /^Bearer [A-Za-z0-9\-._~+/]+=*$/.test(a); }

Try / catch

try {
  const res = await tool.invoke(params, { authToken: accessToken });
} catch (e) {
  if (/error creating service from OAuth access token/.test(e.message)) {
    accessToken = await refreshAccessToken(); // token expired or malformed
    return tool.invoke(params, { authToken: accessToken });
  }
  throw e;
}

Prevention

When it happens

Trigger: A user OAuth token passed via the client's Authorization header is malformed, expired, or cannot be parsed by the oauth2/google machinery inside s.ServiceCreator()(tokenStr); or the ServiceCreator itself is misconfigured (wrong endpoint/universe domain).

Common situations: MCP client sends an expired or truncated access token in the Authorization header; token lacks required scopes (cloud-platform); a custom service URL with an unreachable private endpoint was configured; clock skew invalidating the token.

Related errors


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