passbolt/passbolt_api · warning · Cake\Http\Exception\NotFoundException

Registration is not opened to public. This is due to a…

Error message

Registration is not opened to public. This is due to a security setting. Please contact your administrator.

What it means

Passbolt's registration endpoint is gated by the config key `passbolt.security.preventEmailEnumeration` (UsersRecoverController::PREVENT_EMAIL_ENUMERATION_CONFIG_KEY). When self-registration is already closed (an earlier check in assertIsSelfRegistrationOpen) or when email-enumeration prevention is enabled, the controller throws a 404 NotFoundException instead of revealing whether registration is open. The generic message is intentional: it avoids leaking account/registration state to unauthenticated visitors.

Solutions

  1. Check whether public registration should be open; if yes, set 'preventEmailEnumeration' => false under 'passbolt.security' in config and clear the cache (cake cache clear_all).
  2. If registration should stay admin-controlled, direct users to an admin: create the account via UsersAdminController or the 'register' command, and send the invitation email manually.
  3. If the intent is only to hide registration from enumeration while still allowing signup, disable preventEmailEnumeration and instead rely on the registration-open check.
  4. Verify which check is firing: if self-registration itself is closed, re-enabling it requires enabling the self-registration plugin/settings rather than only the enumeration flag.

Example fix

// before (config/passbolt.php)
'passbolt' => ['security' => ['preventEmailEnumeration' => true]]
// after (allow public registration)
'passbolt' => ['security' => ['preventEmailEnumeration' => false]]
Defensive patterns

Strategy: validation

Validate before calling

// PHP client-side pre-check: only call /users/register when the instance allows it
const settings = await fetch(baseUrl + '/healthcheck/status.json').then(r => r.json());
if (!settings.body.application.registrationPublic) {
  throw new Error('Public registration is disabled on this instance; ask an admin to create the account.');
}

Try / catch

// PHP (CakePHP Http client)
try {
    $response = $http->get($baseUrl . '/users/register.json');
} catch (Cake\Http\Exception\HttpException $e) {
    if ($e->getCode() === 404) {
        // registration closed or email enumeration prevention active
        throw new DomainException('Signup unavailable on this passbolt instance; contact the administrator.', 0, $e);
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling GET or POST /users/register (registerGet/registerPost) when (a) public self-registration is disabled — the first check throws a NotFoundException just before this code — or (b) Configure::read('passbolt.security.preventEmailEnumeration') is truthy.

Common situations: Deployments with passbolt.php or config/passbolt.default.php setting 'passbolt.security' => ['preventEmailEnumeration' => true]; admins who disabled the self-registration plugin (passbolt.plugins.accountSettings / registration settings); users trying to reach the /register route on a hardened production instance where only admins can create accounts; staging instances inheriting hardened production config.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/d6b4a940029d2c65. Report an issue: GitHub.

Appendix: source

Thrown at src/Controller/Users/UsersRegisterController.php:116

    }

    /**
     * @param \Passbolt\SelfRegistration\Service\DryRun\SelfRegistrationDryRunServiceInterface $dryRunService dry run service
     * @return void
     * @throws \Cake\Http\Exception\NotFoundException if the user cannot register
     */
    protected function assertIsSelfRegistrationOpen(SelfRegistrationDryRunServiceInterface $dryRunService): void
    {
        if (!$dryRunService->isSelfRegistrationOpen()) {
            $msg = __('Registration is not opened to public.') . ' ';
            $msg .= __('Please contact your administrator.');
            throw new NotFoundException($msg);
        }
        if (Configure::read(UsersRecoverController::PREVENT_EMAIL_ENUMERATION_CONFIG_KEY)) {
            $msg = __('Registration is not opened to public.') . ' ';
            $msg .= __('This is due to a security setting.') . ' ';
            $msg .= __('Please contact your administrator.');
            throw new NotFoundException($msg);
        }
    }
}

View on GitHub (pinned to 31c1bbc10f)