{"record":{"id":"3c6c52ed00f80c33","repo":"passbolt/passbolt_api","slug":"the-authentication-token-is-not-active","errorCode":null,"errorMessage":"The authentication token is not active.","messagePattern":"The authentication token is not active\\.","errorType":"http","errorClass":"ForbiddenException","httpStatus":403,"severity":"error","filePath":"plugins/PassboltCe/Mobile/src/Service/Transfers/TransfersUpdateService.php","lineNumber":173,"sourceCode":"     * - Authentication token is expired\n     * @return void\n     */\n    private function assertOperationIsAllowed(Transfer $transfer, UserAccessControl $uac): void\n    {\n        if ($transfer->user_id !== $uac->getId()) {\n            throw new ForbiddenException(__('This operation is not allowed for this user.'));\n        }\n        if (!isset($transfer->authentication_token)) {\n            throw new ForbiddenException(__('The authentication token is missing.'));\n        }\n        if ($transfer->authentication_token->user_id !== $uac->getId()) {\n            throw new ForbiddenException(__('The authentication token is not valid for this user.'));\n        }\n        if ($transfer->authentication_token->type !== AuthenticationToken::TYPE_MOBILE_TRANSFER) {\n            throw new ForbiddenException(__('The authentication token type is invalid.'));\n        }\n        if ($transfer->authentication_token->active !== true) {\n            throw new ForbiddenException(__('The authentication token is not active.'));\n        }\n        if ($transfer->authentication_token->isExpired()) {\n            throw new ForbiddenException(__('The authentication token is expired.'));\n        }\n    }\n\n    /**\n     * Return an updated transfer entity.\n     *\n     * @param \\Passbolt\\Mobile\\Model\\Entity\\Transfer $transfer entity\n     * @param array $data data\n     * @return \\Passbolt\\Mobile\\Model\\Entity\\Transfer\n     */\n    private function patchTransferEntity(Transfer $transfer, array $data): Transfer\n    {\n        $data['total_pages'] = $transfer->total_pages;\n\n        return $this->Transfers->patchEntity($transfer, $data, [","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Mobile/src/Service/Transfers/TransfersUpdateService.php#L155-L191","documentation":"Authorization/state check in TransfersUpdateService::assertOperationIsAllowed() (invoked by update()): a user may only update a transfer they own via an authentication token that belongs to them and is still in an active (non-expired, non-completed) state. This error fires when the transfer's authentication token entity exists but is no longer active — typically an expired or already-consumed token — so the transfer resume/continuation is refused with HTTP 403 and the client must start a new transfer or re-request a token.","triggerScenarios":"Updating a transfer after its token was deactivated — e.g. after a previous transfer completed, after calling the token's delete/inactivate endpoint, or when the mobile client retries with an old token.","commonSituations":"Client caching an old token across transfer restarts; duplicate transfer attempts where the second consumed the token; server-side tests reusing fixtures with inactive tokens.","solutions":["Generate a fresh active token by restarting the mobile transfer setup","Check authentication_tokens.active = 1 for the token in use","Avoid caching tokens across transfer sessions; fetch the token each flow"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const token = transfer.authenticationToken;\nif (token && token.active !== true) {\n  // token inactive: request a fresh one via transfer setup\n  await restartTransferSetup();\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.updateTransfer(transferId, payload);\n} catch (e) {\n  if (e.code === 403 && e.message.includes('token is not active')) {\n    await restartTransferSetup(); // get a new active token\n  }\n}","preventionTips":["Do not cache tokens across transfer restarts","Treat a completed/aborted transfer's token as permanently dead","Verify token.active before resuming an interrupted transfer"],"tags":["mobile","transfer","authentication-token","inactive"],"backgroundTag":"invalid-identifier","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"}