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

The user does not exist or has been deleted.

Error message

The user does not exist or has been deleted.

What it means

findUser loads the user via Users->findView($userId, Role::GUEST) with its Gpgkey, logging any query exception and converting it to NotFoundException 'The user does not exist or has been deleted.' This first raise covers the case where the query itself throws (invalid UUID, DB error) or is otherwise exceptional. It guards the JWT flow against tokens referencing missing users.

Solutions

  1. Re-authenticate to obtain a fresh token: the token's user id is invalid, so it cannot be reused.
  2. Verify the user actually exists and is not deleted (users back-end listing / database).
  3. Check logs for the logged exception message to distinguish malformed id vs DB failure.
  4. Purge invalid refresh tokens for deleted users so clients fall back to full login.
  5. If DB errors recur, check database health and migration status.
Defensive patterns

Strategy: try-catch

Validate before calling

const isUuid = (v) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v);
if (!isUuid(subClaim)) forceFullLogin();

Try / catch

try { await authenticatedCall(); } catch (e) { if (e.message.includes('does not exist or has been deleted')) { clearTokens(); redirectToLogin(); } else throw e; }

Prevention

When it happens

Trigger: Presenting a JWT whose 'sub' claim contains a user id that is malformed (not a UUID), fails the view query, or triggers a DB exception during lookup during GPG-JWT authentication.

Common situations: Stale tokens surviving a user hard-delete; corrupted or hand-crafted JWT payloads; database connectivity errors during authentication; tokens issued before a server migration changed user data.

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/6302e08f63614682. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/JwtAuthentication/src/Authenticator/GpgJwtAuthenticator.php:284

    /**
     * @param string $userId uuid
     * @throws \Cake\Http\Exception\NotFoundException if the user cannot be found, is deleted, is not active
     * @return \App\Model\Entity\User
     */
    private function findUser(string $userId): User
    {
        try {
            /** @var \App\Model\Table\UsersTable $Users */
            $Users = TableRegistry::getTableLocator()->get('Users');

            /** @var \App\Model\Entity\User|null $userData */
            $userData = $Users->findView($userId, Role::GUEST)
                ->contain('Gpgkeys')
                ->first();
        } catch (Exception $exception) {
            Log::error($exception->getMessage());
            throw new NotFoundException(__('The user does not exist or has been deleted.'));
        }

        if (!isset($userData)) {
            throw new NotFoundException(__('The user does not exist or has been deleted.'));
        }

        if ($userData->isDisabled()) {
            throw new NotFoundException(__('The user does not exist or has been deleted.'));
        }

        return $userData;
    }

    /**
     * @throws \InvalidArgumentException if the challenge is missing
     * @throws \Cake\Http\Exception\BadRequestException if the challenge is invalid
     * @return string
     */

View on GitHub (pinned to 31c1bbc10f)