googleapis/mcp-toolbox · error

retrieved token is invalid or expired

Error message

retrieved token is invalid or expired

What it means

GetIAMAccessToken validates the token returned by the TokenSource using token.Valid(), which checks that the access token is non-empty, has an expiry, and is not expired. This error means the oauth2 library handed back a token that failed those invariants — practically a bug/edge case in credential setup, such as a credentials type that yields empty access tokens.

Source

Thrown at internal/sources/util.go:158

		return "", fmt.Errorf("username from ADC cannot be an empty string")
	}

	return username, nil
}

func GetIAMAccessToken(ctx context.Context) (string, error) {
	creds, err := google.FindDefaultCredentials(ctx, "https://www.googleapis.com/auth/cloud-platform")
	if err != nil {
		return "", fmt.Errorf("failed to find default credentials (run 'gcloud auth application-default login'?): %w", err)
	}

	token, err := creds.TokenSource.Token() // This gets an oauth2.Token
	if err != nil {
		return "", fmt.Errorf("failed to get token from token source: %w", err)
	}

	if !token.Valid() {
		return "", fmt.Errorf("retrieved token is invalid or expired")
	}
	return token.AccessToken, nil
}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Re-generate credentials: 'gcloud auth application-default login' or a fresh service account key
  2. Fix system clock synchronization (chrony/ntp)
  3. Verify the ADC key file is a genuine, complete Google-issued credential file
Defensive patterns

Strategy: retry

Validate before calling

// Validate token before use
function tokenLooksValid(t: { access_token?: string; expiry_date?: number }): boolean {
  return !!t.access_token && typeof t.expiry_date === "number" && t.expiry_date > Date.now();
}

Type guard

function isUsableToken(t: { access_token: string; expiry_date?: number } | undefined | null):
  t is { access_token: string; expiry_date?: number } {
  return !!t && typeof t.access_token === "string" && t.access_token.length > 0;
}

Try / catch

try {
  const token = await getIAMAccessToken(ctx);
} catch (err) {
  if (String(err).includes("retrieved token is invalid or expired")) {
    // force-refresh credentials once, then retry
    await refreshCredentials();
    return getIAMAccessToken(ctx);
  }
  throw err;
}

Prevention

When it happens

Trigger: creds.TokenSource.Token() returns successfully but the token has an empty AccessToken, zero Expiry, or is already expired at return time — e.g. unusual/invalid credential configurations or mocked/edge-case ADC sources.

Common situations: ADC pointing to a key file whose token endpoint returns an empty access token; heavily skewed system clocks making the token immediately expired; using non-standard credential files hand-crafted or copied between environments.

Understand the failure class

Related errors


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