{"record":{"id":"ef42936effce795b","repo":"BerriAI/litellm","slug":"timed-out-waiting-for-device-authorization","errorCode":null,"errorMessage":"Timed out waiting for device authorization","messagePattern":"Timed out waiting for device authorization","errorType":"exception","errorClass":"GetAccessTokenError","httpStatus":408,"severity":"error","filePath":"litellm/llms/chatgpt/authenticator.py","lineNumber":243,"sourceCode":"                    continue\n                resp.raise_for_status()\n            except httpx.HTTPStatusError as exc:\n                status_code = exc.response.status_code if exc.response else None\n                if status_code in (403, 404):\n                    time.sleep(max(interval, DEVICE_CODE_POLL_SLEEP_SECONDS))\n                    continue\n                raise GetAccessTokenError(\n                    message=f\"Polling failed: {exc}\",\n                    status_code=exc.response.status_code,\n                )\n            except Exception as exc:\n                raise GetAccessTokenError(\n                    message=f\"Polling failed: {exc}\",\n                    status_code=400,\n                )\n            time.sleep(max(interval, DEVICE_CODE_POLL_SLEEP_SECONDS))\n\n        raise GetAccessTokenError(\n            message=\"Timed out waiting for device authorization\",\n            status_code=408,\n        )\n\n    def _exchange_code_for_tokens(self, code_data: dict[str, str]) -> dict[str, str]:\n        try:\n            client: Final = _get_httpx_client()\n            redirect_uri: Final = f\"{CHATGPT_AUTH_BASE}/deviceauth/callback\"\n            body: Final = (\n                \"grant_type=authorization_code\"\n                f\"&code={code_data['authorization_code']}\"\n                f\"&redirect_uri={redirect_uri}\"\n                f\"&client_id={CHATGPT_CLIENT_ID}\"\n                f\"&code_verifier={code_data['code_verifier']}\"\n            )\n            resp: Final = client.post(\n                CHATGPT_OAUTH_TOKEN_URL,\n                headers={\"Content-Type\": \"application/x-www-form-urlencoded\"},","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/chatgpt/authenticator.py#L225-L261","documentation":"Raised as `GetAccessTokenError` (status 408) when the device-authorization polling loop exhausts its attempts without the user approving (or denying) the login. The 408 status signals a client-side timeout waiting for human action, not a server failure.","triggerScenarios":"Starting ChatGPT device login and never visiting the verification URL / never entering the user code, or taking longer than the loop's total wait budget to approve. The loop exits after its max iterations and raises this.","commonSituations":"Headless servers where the user code is printed to logs nobody watches; automation invoking the chatgpt provider without a human to complete browser auth; user stepping away mid-login.","solutions":["Re-run login and immediately open the verification URL shown in the output and enter the code.","For headless machines, run login once on a machine with a browser, then copy the resulting auth file/tokens to the server.","Watch stdout/logs for the user code during the flow — it is time-limited.","For non-interactive workloads, use a different auth mechanism or provider that does not need device login."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    tokens = authenticator.get_access_token()\nexcept GetAccessTokenError as e:\n    if e.status_code == 408:\n        print(\"Login timed out: re-run and approve the code at the shown URL promptly.\")\n    raise","preventionTips":["Watch the terminal/logs for the user code and approve immediately.","On headless boxes, log in once locally and copy the auth file to the server.","Do not script device login unattended."],"tags":["chatgpt","oauth","device-flow","timeout","auth"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}