BerriAI/litellm · error · GetAccessTokenError

Timed out waiting for device authorization

Error message

Timed out waiting for device authorization

What it means

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.

Source

Thrown at litellm/llms/chatgpt/authenticator.py:243

                    continue
                resp.raise_for_status()
            except httpx.HTTPStatusError as exc:
                status_code = exc.response.status_code if exc.response else None
                if status_code in (403, 404):
                    time.sleep(max(interval, DEVICE_CODE_POLL_SLEEP_SECONDS))
                    continue
                raise GetAccessTokenError(
                    message=f"Polling failed: {exc}",
                    status_code=exc.response.status_code,
                )
            except Exception as exc:
                raise GetAccessTokenError(
                    message=f"Polling failed: {exc}",
                    status_code=400,
                )
            time.sleep(max(interval, DEVICE_CODE_POLL_SLEEP_SECONDS))

        raise GetAccessTokenError(
            message="Timed out waiting for device authorization",
            status_code=408,
        )

    def _exchange_code_for_tokens(self, code_data: dict[str, str]) -> dict[str, str]:
        try:
            client: Final = _get_httpx_client()
            redirect_uri: Final = f"{CHATGPT_AUTH_BASE}/deviceauth/callback"
            body: Final = (
                "grant_type=authorization_code"
                f"&code={code_data['authorization_code']}"
                f"&redirect_uri={redirect_uri}"
                f"&client_id={CHATGPT_CLIENT_ID}"
                f"&code_verifier={code_data['code_verifier']}"
            )
            resp: Final = client.post(
                CHATGPT_OAUTH_TOKEN_URL,
                headers={"Content-Type": "application/x-www-form-urlencoded"},

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Re-run login and immediately open the verification URL shown in the output and enter the code.
  2. For headless machines, run login once on a machine with a browser, then copy the resulting auth file/tokens to the server.
  3. Watch stdout/logs for the user code during the flow — it is time-limited.
  4. For non-interactive workloads, use a different auth mechanism or provider that does not need device login.
Defensive patterns

Strategy: try-catch

Try / catch

try:
    tokens = authenticator.get_access_token()
except GetAccessTokenError as e:
    if e.status_code == 408:
        print("Login timed out: re-run and approve the code at the shown URL promptly.")
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/ef42936effce795b. Report an issue: GitHub.