{"record":{"id":"1e63def7e66478ae","repo":"passbolt/passbolt_api","slug":"the-authentication-token-is-not-valid-1e63de","errorCode":null,"errorMessage":"The authentication token is not valid.","messagePattern":"The authentication token is not valid\\.","errorType":"validation","errorClass":"CustomValidationException","httpStatus":400,"severity":"error","filePath":"src/Service/AuthenticationTokens/AuthenticationTokenGetService.php","lineNumber":79,"sourceCode":"     * @throws \\Cake\\Http\\Exception\\BadRequestException if token id is not a valid uuid\n     */\n    public function getActiveNotExpiredOrFail(\n        string $token,\n        string $userId,\n        string $type,\n        ?string $expiry = null\n    ): AuthenticationToken {\n        $tokenEntity = $this->getActiveOrFail($token, $userId, $type);\n\n        if ($tokenEntity->isExpired($expiry)) {\n            $tokenEntity->set('active', false);\n            $this->AuthenticationTokens->save($tokenEntity);\n            $error = [\n                'token' => [\n                    'expired' => __('The token is expired.'),\n                ],\n            ];\n            throw new CustomValidationException(__('The authentication token is not valid.'), $error);\n        }\n\n        return $tokenEntity;\n    }\n\n    /**\n     * Get active token or fail.\n     *\n     * @param string $token authentication token\n     * @param string $userId user ID\n     * @param string $type token type\n     * @return \\App\\Model\\Entity\\AuthenticationToken\n     * @throws \\Cake\\Http\\Exception\\NotFoundException if token is not found\n     * @throws \\App\\Error\\Exception\\CustomValidationException if the token is inactive\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if token id is not a valid uuid\n     */\n    public function getActiveOrFail(string $token, string $userId, string $type): AuthenticationToken\n    {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Service/AuthenticationTokens/AuthenticationTokenGetService.php#L61-L97","documentation":"getActiveNotExpiredOrFail finds a matching token but, when it is past expiry, marks it inactive, saves, and throws CustomValidationException('The authentication token is not valid.') with a 'token.expired' validation error so clients know the token expired.","triggerScenarios":"Calling getActiveNotExpiredOrFail (via getNotCompletedOrFail) with a token whose expiry timestamp is in the past but that is still active in the DB.","commonSituations":"User opens a setup/recover email link days after receiving it; tokens left from before a deployment pause; clock/timezone drift making tokens appear expired.","solutions":["Request a new token: resend the setup/recover/verify email.","Verify server timezone and token TTL configuration if expiry seems premature.","Show an 'expired link' UI instead of a generic error by inspecting the token.expired error key.","Clean up expired tokens with the standard purge command to keep the table tidy."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $token = $service->getActiveNotExpiredOrFail($token, $userId, $type);\n} catch (CustomValidationException $e) {\n    if (isset($e->getErrors()['token']['expired'])) {\n        // offer 'resend email' flow\n    }\n}","preventionTips":["Show token expiry time in the email and UI","Automatically offer a resend flow when expired","Monitor server clock/NTP to avoid premature expiry"],"tags":["php","auth-tokens","token-expired"],"backgroundTag":"jwt-token-expired","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}