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
- 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.
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
- 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.
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
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Failed to request device code: {exc}
- Polling failed: {exc}
- Device code response missing fields: {data}
- Token exchange failed: {exc}
- Refresh token failed: {exc}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/ef42936effce795b.
Report an issue: GitHub.