passbolt/passbolt_api · error · ForbiddenException

The authentication token is not valid for this user.

Error message

The authentication token is not valid for this user.

What it means

Ownership guard for mobile transfers: the authentication token attached to the transfer belongs to a different user than the one performing the operation, so the token is not valid for this user and the transfer update is denied with 403.

Solutions

  1. Re-run the mobile transfer setup as the currently logged-in user to get a matching token
  2. Ensure the token used is the one returned for this user's transfer-create call
  3. Delete stale tokens for the old account and start a new transfer
Defensive patterns

Strategy: validation

Validate before calling

const me = await api.getLoggedInUser();
if (transfer.authenticationToken && transfer.authenticationToken.userId !== me.id) {
  throw new Error('Token/user mismatch: restart transfer as current user');
}

Try / catch

try {
  await api.updateTransfer(transferId, payload);
} catch (e) {
  if (e.code === 403 && e.message.includes('not valid for this user')) {
    // token belongs to another user; recreate transfer + token for this user
  }
}

Prevention

When it happens

Trigger: Updating a transfer with a valid mobile-transfer token that was issued to another user — e.g. after switching accounts on the device while keeping the old transfer id/token, or sharing transfer credentials between accounts.

Common situations: Account switch on a mobile device mid-setup; restoring a backup onto a device logged in as a different user; mismatched token transfer between test fixtures.

Understand the failure class

Related errors


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

Appendix: source

Thrown at plugins/PassboltCe/Mobile/src/Service/Transfers/TransfersUpdateService.php:167

     * Check if operation is allowed
     *
     * @param \Passbolt\Mobile\Model\Entity\Transfer $transfer entity
     * @param \App\Utility\UserAccessControl $uac user access control object
     * @throws \Cake\Http\Exception\ForbiddenException if operation is not allowed for example:
     * - Transfer or AuthToken is for another user
     * - Authentication token is expired
     * @return void
     */
    private function assertOperationIsAllowed(Transfer $transfer, UserAccessControl $uac): void
    {
        if ($transfer->user_id !== $uac->getId()) {
            throw new ForbiddenException(__('This operation is not allowed for this user.'));
        }
        if (!isset($transfer->authentication_token)) {
            throw new ForbiddenException(__('The authentication token is missing.'));
        }
        if ($transfer->authentication_token->user_id !== $uac->getId()) {
            throw new ForbiddenException(__('The authentication token is not valid for this user.'));
        }
        if ($transfer->authentication_token->type !== AuthenticationToken::TYPE_MOBILE_TRANSFER) {
            throw new ForbiddenException(__('The authentication token type is invalid.'));
        }
        if ($transfer->authentication_token->active !== true) {
            throw new ForbiddenException(__('The authentication token is not active.'));
        }
        if ($transfer->authentication_token->isExpired()) {
            throw new ForbiddenException(__('The authentication token is expired.'));
        }
    }

    /**
     * Return an updated transfer entity.
     *
     * @param \Passbolt\Mobile\Model\Entity\Transfer $transfer entity
     * @param array $data data
     * @return \Passbolt\Mobile\Model\Entity\Transfer

View on GitHub (pinned to 31c1bbc10f)