passbolt/passbolt_api · error · BadRequestException
Single sign-on failed. The
Error message
Single sign-on failed. The {0} claim is not present, please contact your administrator. What it means
PingOneResourceOwner->getEmail() requires the configured email claim (default 'email') in the resource-owner payload returned by PingOne. When the claim key is absent or null it throws a BadRequestException telling the administrator which claim is missing. This happens because the PingOne application is not mapping the email attribute into the token or a custom claim name is configured that the IdP does not send.
Solutions
- In the PingOne admin console, add an attribute mapping so the email claim is included in the token.
- Check the claim name configured in passbolt SSO settings matches exactly what PingOne sends (case-sensitive).
- Ensure the PingOne user has an email populated on their profile.
- If a custom claim is intended, update emailClaimField in the passbolt settings to that key and re-test.
Example fix
// before (custom claim not sent) 'emailClaimField' => 'mail', // after (use claim PingOne actually sends) 'emailClaimField' => 'email',
Defensive patterns
Strategy: validation
Validate before calling
$payload = json_decode(base64_decode(str_replace('_', '/', str_replace('-', '_', explode('.', $jwt)[1]))), true);
$claim = $settings->getClaimForEmail() ?: 'email';
if (!isset($payload[$claim]) || $payload[$claim] === null) { throw new BadRequestException("SSO token is missing the {$claim} claim."); } Type guard
function hasEmailClaim(array $data, string $field): bool { return isset($data[$field]) && is_string($data[$field]) && filter_var($data[$field], FILTER_VALIDATE_EMAIL) !== false; } Try / catch
try { $email = $resourceOwner->getEmail(); } catch (BadRequestException $e) { $this->log($e->getMessage()); return $this->renderSsoError('Your identity provider did not send the required email attribute.'); } Prevention
- Add the email attribute mapping in the PingOne application token config
- Keep the claim name in passbolt settings identical to what the IdP sends
- Ensure every IdP user has an email populated
- Write an integration test decoding a sample token with the configured claim
When it happens
Trigger: Decoding a PingOne ID token / calling getUser() where the resource-owner array lacks the configured emailClaimField; using a custom claim name that PingOne does not include in the token.
Common situations: PingOne app 'Token' mapping does not include the email attribute; passbolt SSO settings define a custom claim (e.g. 'mail') but PingOne sends 'email'; user account in PingOne has no email set.
Related errors
- $data['error'] (dynamic provider error)
- Invalid provider data. Expected PingOne settings.
- Invalid provider. Expected PingOne.
- No valid SSO settings found.
- Single sign-on failed. Invalid nonce.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/f9d6f7be54fdb47c.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Utility/PingOne/ResourceOwner/PingOneResourceOwner.php:54
$this->emailClaimField = $emailClaimField ?? SsoSetting::PINGONE_EMAIL_CLAIM_EMAIL;
}
/**
* Retrieves email of the resource owner.
*
* @return string
* @throws \Cake\Http\Exception\BadRequestException When email claim field is not present in the data.
*/
public function getEmail(): string
{
if (!isset($this->data[$this->emailClaimField]) || is_null($this->data[$this->emailClaimField])) {
$msg = __('Single sign-on failed.') . ' ';
$msg .= __(
'The {0} claim is not present, please contact your administrator.',
$this->emailClaimField
);
throw new BadRequestException($msg);
}
return $this->data[$this->emailClaimField];
}
}
View on GitHub (pinned to 31c1bbc10f)