{"record":{"id":"98b4515fe7e45b2b","repo":"passbolt/passbolt_api","slug":"the-authentication-token-does-not-exist-or-has-been-deleted-98b451","errorCode":null,"errorMessage":"The authentication token does not exist or has been deleted.","messagePattern":"The authentication token does not exist or has been deleted\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/SsoRecover/src/Controller/OAuth2/OAuth2RecoverSuccessController.php","lineNumber":54,"sourceCode":"        $this->Authentication->allowUnauthenticated(['ssoRecoverSuccess']);\n    }\n\n    /**\n     * @return void\n     */\n    public function ssoRecoverSuccess(): void\n    {\n        if ($this->request->is('json')) {\n            throw new BadRequestException(__('Ajax/Json request not supported.'));\n        }\n\n        $this->User->assertNotLoggedIn();\n        $token = $this->getTokenFromUrlQuery();\n\n        try {\n            (new SsoAuthenticationTokenGetService())->getActiveNotExpiredOrFail($token, SsoState::TYPE_SSO_RECOVER);\n        } catch (RecordNotFoundException $e) {\n            throw new BadRequestException(\n                __('The authentication token does not exist or has been deleted.'),\n                null,\n                $e\n            );\n        } catch (CustomValidationException $e) {\n            throw new BadRequestException(\n                __('The authentication token has been expired.'),\n                null,\n                $e\n            );\n        }\n\n        $this->viewBuilder()\n            ->setTheme('Passbolt/Sso')\n            ->setLayout('default')\n            ->setTemplatePath('success')\n            ->setTemplate('stage3');\n    }","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/SsoRecover/src/Controller/OAuth2/OAuth2RecoverSuccessController.php#L36-L72","documentation":"Thrown when the SSO_RECOVER authentication token in the URL query is not found as an active, non-expired token; the RecordNotFoundException from SsoAuthenticationTokenGetService::getActiveNotExpiredOrFail is wrapped in this BadRequestException by the OAuth2 recover-success controller.","triggerScenarios":"GET /sso/recover/success?token=... where the token matches no active record: already consumed by a previous success request, deleted, mistyped/truncated, or issued by another environment.","commonSituations":"Double-submission or refresh of the success page after the single-use token was consumed; replaying an expired recovery link; migrating between instances mid-recovery.","solutions":["Restart the SSO recovery flow to obtain a new token and use the fresh link once only.","Check the token parameter for truncation or encoding issues in the URL.","Ensure the request goes to the same passbolt instance that issued the token.","Do not refresh or re-open the success URL after it has completed; the token is single-use."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const token = new URLSearchParams(window.location.search).get('token');\nif (!token || /\\s/.test(token)) console.warn('SSO recover token missing or malformed; restart the flow.');","typeGuard":"function hasToken(url) {\n  const t = new URL(url, window.location.origin).searchParams.get('token');\n  return typeof t === 'string' && t.length >= 16;\n}","tryCatchPattern":"try {\n  await completeOauth2SsoRecoverSuccess(token);\n} catch (e) {\n  if (e.message.includes('does not exist or has been deleted')) {\n    restartSsoRecoverFlow(); // token single-use; get a new one\n  }\n}","preventionTips":["Never reuse or refresh the success URL; the token is consumed on first use.","Verify tokens survive redirect chains intact (no truncation).","Keep the recovery flow within one environment.","If a flow fails, restart from the recover-login endpoint rather than retrying the same token."],"tags":["sso","authentication-token","token-not-found","oauth2"],"backgroundTag":"record-not-found","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"}