passbolt/passbolt_api · error · BadRequestException

The user does not exist or is already active or is disabled.

Error message

The user does not exist or is already active or is disabled.

What it means

The setup-start info endpoint requires a user who exists and is inactive, not deleted and not disabled. getNotActiveNotDeletedNotDisabledOrFail threw BadRequestException with this combined message (deliberately indistinguishable between the conditions to avoid user enumeration).

Solutions

  1. If setup was already completed, use the login page instead
  2. Have an admin verify the user's status and resend the invite if it was deleted/disabled
  3. Double-check the userId UUID in the setup URL against the invitation email
  4. Re-register/re-invite the user to generate a fresh token if the account state is unrecoverable
Defensive patterns

Strategy: validation

Validate before calling

$user = $this->Users->find()->where(['id' => $userId])->first();
if (!$user || $user->active || $user->deleted || $user->disabled) {
    // do not attempt setup-start; redirect to login or re-invite
}

Try / catch

try {
    $info = $setupStartUserInfoService->getInfo($userId, $token, $data);
} catch (\Cake\Http\Exception\BadRequestException $e) {
    // user unknown/active/deleted/disabled: show generic guidance
}

Prevention

When it happens

Trigger: GET /setup/start/:userId/:token where the user id is unknown, the account is already active, was deleted, or is disabled.

Common situations: Opening an invite link after setup already finished; account disabled by admin before the user started; wrong/typoed UUID from the email link.

Understand the failure class

Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.

Related errors


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

Appendix: source

Thrown at src/Service/Setup/SetupStartUserInfoService.php:37

use App\Model\Entity\AuthenticationToken;
use App\Model\Entity\User;
use App\Service\AuthenticationTokens\AuthenticationTokenGetService;
use App\Service\Users\UserGetService;
use Cake\Http\Exception\BadRequestException;
use Cake\Http\Exception\NotFoundException;

class SetupStartUserInfoService implements SetupStartInfoServiceInterface
{
    /**
     * @inheritDoc
     */
    public function getInfo(string $userId, string $token, ?array $data): array
    {
        try {
            $user = (new UserGetService())->getNotActiveNotDeletedNotDisabledOrFail($userId);
        } catch (NotFoundException $exception) {
            throw new BadRequestException(__('The user does not exist or is already active or is disabled.'));
        }

        $this->assertAuthToken($user, $token);

        $data['user'] = $user;

        return $data;
    }

    /**
     * Check the setup token
     *
     * @param \App\Model\Entity\User $user user attempting to recover
     * @param string $token uuid of the token
     * @throw BadRequestException if the token is not valid
     * @return void
     */
    private function assertAuthToken(User $user, string $token): void

View on GitHub (pinned to 31c1bbc10f)