BookStackApp/BookStack · error · SamlException
errors.saml_no_email_address
Error message
errors.saml_no_email_address
What it means
SamlException thrown by BookStack's SAML2 login flow when the IdP response contains user details but no email address. BookStack requires an email to find or register the local user matching the SAML identity, so a response lacking the email attribute is rejected. The check runs in processLoginCallback after the SAML attributes have been parsed into $userDetails.
Source
Thrown at app/Access/Saml2Service.php:361
public function processLoginCallback(string $samlID, array $samlAttributes): User
{
$userDetails = $this->getUserDetails($samlID, $samlAttributes);
$isLoggedIn = auth()->check();
if ($this->shouldSyncGroups()) {
$userDetails['groups'] = $this->getUserGroups($samlAttributes);
}
if ($this->config['dump_user_details']) {
throw new JsonDebugException([
'id_from_idp' => $samlID,
'attrs_from_idp' => $samlAttributes,
'attrs_after_parsing' => $userDetails,
]);
}
if (empty($userDetails['email'])) {
throw new SamlException(trans('errors.saml_no_email_address'));
}
if ($isLoggedIn) {
throw new SamlException(trans('errors.saml_already_logged_in'), '/login');
}
$user = $this->registrationService->findOrRegister(
$userDetails['name'],
$userDetails['email'],
$userDetails['external_id']
);
if ($this->shouldSyncGroups()) {
$this->groupSyncService->syncUserWithFoundGroups($user, $userDetails['groups'], $this->config['remove_from_groups']);
}
$this->loginService->login($user, 'saml2');
View on GitHub (pinned to 18f8469a1c)
Solutions
- Check the email attribute name configured for the SAML2 IdP in BookStack (Admin > SAML2 settings / 'External user id' style option mapping) and set it to the exact attribute the IdP releases (e.g. http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress or mail)
- Verify in the IdP admin console that the email attribute/claim is included in the assertion for this service provider
- Inspect the debug dump (attrs_from_idp / attrs_after_parsing logged when debug is enabled) to see which attributes actually arrived and adjust the mapping
- If the IdP cannot send email, enable the 'email is determined from username/ID' style fallback by mapping email to an attribute that is always present
Example fix
// before (BookStack saml2 option: email attribute set to a claim the IdP doesn't send) $emailAttributeName = 'email'; // after (match the IdP's actual claim name) $emailAttributeName = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress';
Defensive patterns
Strategy: validation
Validate before calling
// Before invoking the SAML login flow, ensure the IdP attribute mapping yields an email
// (e.g. run a test decode of a sample assertion or verify mapping config)
$attrs = $samlAttributes; // attributes released by IdP
$emailKey = config('saml2.email_attribute');
if (empty($attrs[$emailKey][0] ?? null)) {
throw new \RuntimeException("IdP does not release the '{$emailKey}' attribute; fix attribute mapping/release policy before login.");
} Type guard
function samlDetailsHaveEmail(array $userDetails): bool
{
return isset($userDetails['email']) && filter_var($userDetails['email'], FILTER_VALIDATE_EMAIL) !== false;
} Try / catch
use BookStack\Exceptions\SamlException;
try {
$saml->processLoginCallback();
} catch (SamlException $e) {
if ($e->getMessage() === trans('errors.saml_no_email_address')) {
Log::warning('SAML login failed: IdP sent no email attribute', ['attributes' => $samlAttributes]);
return redirect('/login')->with('error', 'Your identity provider did not share an email address.');
}
throw $e;
} Prevention
- Verify the email attribute name in SAML2 settings matches a claim your IdP actually releases (test with a real assertion)
- Enable BookStack SAML debug (dump attributes) in a staging environment to confirm attribute payload before rollout
- Ask the IdP admin to add the email claim to the SP's attribute release policy
- Add an automated SSO smoke test that asserts the full attribute set, including email
When it happens
Trigger: The IdP sends a successful assertion whose attribute statement does not include an email attribute (e.g. the configured email attribute name in BookStack's saml2 idp settings does not match any attribute the IdP actually releases, or the IdP releases no attributes at all).
Common situations: IdP attribute mapping misconfiguration (email attribute name changed or set to a custom claim the IdP never sends), IdP attribute release policy filtering email for privacy, switching IdPs (e.g. Azure AD sends 'email' only for guest-allowed accounts) or upgrading an IdP that renamed its claims.
Related errors
- errors.saml_already_logged_in
- ($isAnonymous ? trans('errors.ldap_fail_anonymous') : trans(
- Provided path [{$caCertPath}] for LDAP TLS CA certs could no
- Failed to read signing key with error:
- Missing or non-matching token issuer value
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/3902ca274ef780a7.
Report an issue: GitHub.