passbolt/passbolt_api · error · GoogleException
$data['error'] (dynamic provider error)
Error message
$data['error'] (dynamic provider error)
What it means
GoogleProvider::checkResponse() inspects the OAuth2 response body for an 'error' key. When the Google identity provider returns a structured error with string 'error' and 'error_description' fields, a GoogleException is thrown carrying those values. This is the normal path for Google rejecting the JWT-bearer grant or token exchange (bad signature, expired certificate, invalid grant, etc.).
Solutions
- Read the GoogleException message/description — it contains Google's error code (e.g. invalid_grant, invalid_client) and fix the underlying OAuth2 configuration accordingly.
- Regenerate or re-upload the Google service account key and re-run passbolt SSO settings recovery if the key was rotated.
- Check server NTP/clock sync — skewed clocks cause invalid assertion signatures.
- Verify client ID, subject email and scopes configured in passbolt's Google SSO settings match the Google Cloud OAuth consent and service account setup.
- Retry later if the error is transient (Google 5xx with an error payload).
Example fix
// before: JWT assertion signed with a revoked service-account key
// Google responds: {"error":"invalid_grant","error_description":"Invalid JWT Signature."} -> GoogleException
// after: rotate the key and update passbolt SSO settings
bin/cake passbolt sso_settings_generate --provider google
// (then complete recovery as admin) or upload the new JSON key in the admin UI Defensive patterns
Strategy: try-catch
Validate before calling
$decoded = json_decode((string)$response->getBody(), true);
if (isset($decoded['error']) && is_string($decoded['error'])) {
// provider signalled an OAuth2 error; inspect $decoded['error_description'] first
} Try / catch
try {
$token = $provider->getAccessToken('jwt_bearer', [...]);
} catch (\Passbolt\Sso\Error\Exception\GoogleException $e) {
$this->log('Google OAuth error: ' . $e->getMessage() . ' — ' . $e->getOverrideMessage());
// fix the underlying config issue indicated by the Google error code
} Prevention
- Keep server clocks NTP-synced (invalid_grant from skewed signed JWTs)
- Rotate and re-import service-account keys before expiry
- Validate client ID, subject and scopes against Google Cloud settings
- Monitor Google Workspace/Cloud status for IdP-side incidents
When it happens
Trigger: checkResponse() runs after every token/response fetch; Google returns a JSON body like {"error": "invalid_grant", "error_description": "..."} — typically during the jwt_bearer grant when the client assertion is expired, wrongly signed, or the service account/audience is misconfigured.
Common situations: Server clock drift making the signed JWT assertion invalid; Google service-account private key rotated or deleted; wrong subject/scope/audience in the SSO settings; Google-side outages returning error payloads.
Related errors
- $response->getReasonPhrase() (dynamic provider error)
- Single sign-on failed. Provider error
- $data['error'] (dynamic provider error)
- $e->getMessage() from OAuth2Exception during admin SSO…
- error
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/da5c81283b5161b2.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Utility/Google/Provider/GoogleProvider.php:69
/**
* @inheritDoc
*/
protected function createResourceOwner(array $response, AccessToken $token): ResourceOwnerInterface
{
return new GoogleResourceOwner($response);
}
/**
* @inheritDoc
*/
protected function checkResponse(ResponseInterface $response, $data): void
{
if (empty($data['error'])) {
return;
}
if (is_string($data['error']) && isset($data['error_description']) && is_string($data['error_description'])) {
throw new GoogleException($data['error'], $data['error_description']);
} else {
throw new IdentityProviderException(
$response->getReasonPhrase(),
$response->getStatusCode(),
(string)$response->getBody()
);
}
}
}
View on GitHub (pinned to 31c1bbc10f)