passbolt/passbolt_api · error · ForbiddenException
The self registration is disabled.
Error message
The self registration is disabled.
What it means
Thrown by SelfRegistrationEmailDomainsDryRunService::getAllowedDomainsInSettings when the stored self-registration settings exist but contain no allowed_domains data. Raised as ForbiddenException to signal that self-registration is effectively disabled for the instance. Prevents the domain check from running against a null allow-list.
Solutions
- Open Admin > Self Registration and configure at least one allowed domain, or POST valid settings with allowed_domains
- Verify the stored settings property data contains a non-null allowed_domains array
- Check that the email-domains dry-run service matches the configured provider type
- Re-save settings after any upgrade that changed their internal shape
Example fix
// before
// settings stored without domains
{"providers":{"emailDomains":{}}}
// after
{"providers":{"emailDomains":{"allowed_domains":["example.com","company.org"]}}} Defensive patterns
Strategy: fallback
Validate before calling
const settings = await api.get('/self-registration/settings.json');
const domains = settings?.data?.allowed_domains;
if (!Array.isArray(domains) || domains.length === 0) {
// self-registration effectively disabled — don't call dry-run
} Type guard
const hasAllowedDomains = (s) => Array.isArray(s?.data?.allowed_domains) && s.data.allowed_domains.length > 0;
Try / catch
try {
await api.post('/self-registration/dry-run', { email });
} catch (e) {
if (e.status === 403 && /disabled/i.test(e.message)) { /* treat registration as closed */ }
} Prevention
- Configure at least one allowed domain in admin settings
- Re-verify settings after upgrades or environment clones
- Persist settings under the provider the email-domains service reads
- Surface a clear 'registration closed' state instead of calling dry-run blind
When it happens
Trigger: Dry-run when organization settings hold no 'allowed_domains' array (settings saved without domains, provider mismatch, or settings property absent entirely).
Common situations: Admin cleared the allowed domains list; settings stored under a different provider than the email-domains service reads; migration/version change altered the settings payload shape; fresh environment without configuration.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- Registration is not opened to public. Please contact your…
- The self registration plugin is not enabled.
- 500
- A mapping rule for ID attribute could not be found for…
- A mapping rule for username attribute could not be found…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/74ce75ad3368a93f.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/SelfRegistration/src/Service/DryRun/SelfRegistrationEmailDomainsDryRunService.php:65
$email = $form->getData('email');
$this->checkEmailDomainIsAllowed($email, $allowedDomains);
$this->checkEmailNotPreviouslyRegistered($email);
return true;
}
/**
* @return array
* @throws \Cake\Http\Exception\ForbiddenException if no allowed domains are found in the settings.
* @throws \Cake\Http\Exception\InternalErrorException if the settings in DB are not valid.
*/
protected function getAllowedDomainsInSettings(): array
{
// Fetch settings in DB
$settings = $this->getSelfRegistrationSettingsInDB();
$allowedDomains = $settings['data']['allowed_domains'] ?? null;
if (is_null($allowedDomains)) {
throw new ForbiddenException(__('The self registration is disabled.'));
}
return $allowedDomains;
}
/**
* Check that the email complies to the allowed domains
*
* @param string $email Email to check
* @param array $allowedDomains Allowed domains
* @return void
* @throws \App\Error\Exception\ValidationException if the email does not comply
*/
protected function checkEmailDomainIsAllowed(string $email, array $allowedDomains): void
{
/** @var \App\Model\Table\UsersTable $UsersTable */
$UsersTable = TableRegistry::getTableLocator()->get('Users');
if (!$UsersTable->isUsernameCaseSensitive()) {View on GitHub (pinned to 31c1bbc10f)