{"record":{"id":"c9c98da6e76e4375","repo":"passbolt/passbolt_api","slug":"the-authentication-token-is-not-valid-c9c98d","errorCode":null,"errorMessage":"The authentication token is not valid.","messagePattern":"The authentication token is not valid\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Service/Setup/SetupStartUserInfoService.php","lineNumber":61,"sourceCode":"\n        return $data;\n    }\n\n    /**\n     * Check the setup token\n     *\n     * @param \\App\\Model\\Entity\\User $user user attempting to recover\n     * @param string $token uuid of the token\n     * @throw BadRequestException if the token is not valid\n     * @return void\n     */\n    private function assertAuthToken(User $user, string $token): void\n    {\n        try {\n            (new AuthenticationTokenGetService())\n                ->getActiveNotExpiredOrFail($token, $user->id, AuthenticationToken::TYPE_REGISTER);\n        } catch (NotFoundException $exception) {\n            throw new BadRequestException(__('The authentication token is not valid.'));\n        }\n    }\n}\n","sourceCodeStart":43,"sourceCodeEnd":65,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Service/Setup/SetupStartUserInfoService.php#L43-L65","documentation":"The setup start/complete flow looks up an active, non-expired AuthenticationToken of type REGISTER matching the supplied token and user; if none is found a BadRequestException with this message is thrown. The token is the single-use secret proving the invited user's identity.","triggerScenarios":"GET/POST setup endpoints with a token that is expired, already consumed by a previous completion, of the wrong type, belonging to another user, or not a registered token at all.","commonSituations":"Reusing a setup link after it was completed once; waiting too long so the token expired; copying the token from an old email; self-registration tokens mixed up with recover (RECOVER) tokens.","solutions":["Ask an admin to resend the invitation to generate a fresh registration token","Verify the token UUID is complete and paired with the correct userId","Check authentication_tokens table: the row must be active=true, not expired, type=register for this user","Do not re-submit setup after a successful completion; log in instead"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"use Cake\\Validation\\Validation;\n$tokenValid = Validation::uuid($token)\n    && $this->AuthenticationTokens->exists([\n        'token' => $token, 'user_id' => $userId,\n        'type' => AuthenticationToken::TYPE_REGISTER, 'active' => true,\n    ])\n    // plus not expired","typeGuard":null,"tryCatchPattern":"try {\n    $info = $setupStartUserInfoService->getInfo($userId, $token, $data);\n} catch (\\Cake\\Http\\Exception\\BadRequestException $e) {\n    if (str_contains($e->getMessage(), 'authentication token')) {\n        // prompt user to request a new invitation email\n    }\n}","preventionTips":["Complete setup promptly; tokens expire","Never reuse a link after successful completion (token is consumed)","Ensure token type is REGISTER for setup flows (not RECOVER)","Copy the full token UUID from the invitation email"],"tags":["authentication-token","setup","http-400"],"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-21T09:17:21.228Z"}