passbolt/passbolt_api · error · RefreshTokenNotFoundException

No active refresh token matching the request could be found.

Error message

No active refresh token matching the request could be found.

What it means

getUserIdFromToken validates the token UUID and then queries for an active refresh token; if no row matches it throws RefreshTokenNotFoundException ('No active refresh token matching the request could be found'). This means the token is unknown, inactive, or associated with no active session for the authentication flow.

Solutions

  1. Log in again to obtain a valid refresh token; the presented one has no active record.
  2. Verify the client targets the same passbolt instance/environment where the token was issued.
  3. Check the authentication_tokens table for the token id and its active flag to confirm revocation status.
  4. Confirm the request sends the refresh token id (UUID) in the expected request field, not another token value.

Example fix

// before
const userId = await authService.getUserIdFromToken(parsedBody.access_token); // wrong token
// after
const userId = await authService.getUserIdFromToken(parsedBody.refresh_token); // active UUID token
Defensive patterns

Strategy: try-catch

Validate before calling

if (!isUuid(refreshToken)) throw new Error('send the refresh token UUID, not the access token');

Try / catch

try {
  $userId = $authService->getUserIdFromToken($token);
} catch (RefreshTokenNotFoundException $e) {
  throw new AuthenticationException('Unknown or revoked refresh token; re-authenticate', 401, $e);
}

Prevention

When it happens

Trigger: Authenticating the refresh-token flow (JwtRefreshTokenAuthenticator / getUserIdFromToken) with a token id that is not present as an active AuthenticationToken — already consumed, revoked, deleted, or never issued.

Common situations: Client using a refresh token from a different environment (staging vs prod DB); token revoked by an admin or by logout; database re-provisioning wiping authentication_tokens; sending the access token's jti instead of the refresh token id.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltCe/JwtAuthentication/src/Service/RefreshToken/RefreshTokenAuthenticationService.php:42

 */
class RefreshTokenAuthenticationService extends RefreshTokenAbstractService
{
    /**
     * Fetch the user from a provided refresh token.
     *
     * @param string|null $token Token to retrieve
     * @return string refresh token
     * @throws \InvalidArgumentException if the token is not a valid UUIDs
     * @throws \Passbolt\JwtAuthentication\Error\Exception\RefreshToken\RefreshTokenNotFoundException When there is no user associated to this token.
     */
    public function getUserIdFromToken(?string $token): string
    {
        $this->validateRefreshToken($token);

        try {
            return $this->queryRefreshToken($token)->firstOrFail()->get('user_id');
        } catch (RecordNotFoundException $e) {
            throw new RefreshTokenNotFoundException();
        }
    }
}

View on GitHub (pinned to 31c1bbc10f)