BerriAI/litellm · error · RefreshAccessTokenError

Refresh token failed: {exc}

Error message

Refresh token failed: {exc}

What it means

Raised as `RefreshAccessTokenError` when the refresh-token request (`POST` to `CHATGPT_OAUTH_TOKEN_URL` with `grant_type=refresh_token`) returns an HTTP error. This fires on background token refresh inside the ChatGPT provider when the stored refresh token is rejected or the auth server errors.

Source

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

            "id_token": data["id_token"],
        }

    def _refresh_tokens(self, refresh_token: str) -> dict[str, str]:
        try:
            client: Final = _get_httpx_client()
            resp: Final = client.post(
                CHATGPT_OAUTH_TOKEN_URL,
                json={
                    "client_id": CHATGPT_CLIENT_ID,
                    "grant_type": "refresh_token",
                    "refresh_token": refresh_token,
                    "scope": "openid profile email",
                },
            )
            resp.raise_for_status()
            data: Final = resp.json()
        except httpx.HTTPStatusError as exc:
            raise RefreshAccessTokenError(
                message=f"Refresh token failed: {exc}",
                status_code=exc.response.status_code,
            )
        except Exception as exc:
            raise RefreshAccessTokenError(
                message=f"Refresh token failed: {exc}",
                status_code=400,
            )

        access_token: Final = data.get("access_token")
        id_token: Final = data.get("id_token")
        if not access_token or not id_token:
            raise RefreshAccessTokenError(
                message=f"Refresh response missing fields: {data}",
                status_code=400,
            )

        refreshed: Final = {

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Re-run the device login to obtain fresh tokens (`litellm` chatgpt login flow), replacing the stored auth file.
  2. Ensure only one process uses a given auth file to avoid refresh-token rotation races.
  3. Upgrade litellm so the refresh request matches the current API.
  4. If 5xx, retry after a short backoff before forcing re-login.
Defensive patterns

Strategy: try-catch

Try / catch

try:
    resp = litellm.completion(model="chatgpt/gpt-4o", messages=msgs)
except litellm.AuthenticationError as e:
    if is_refresh_failure(e):  # inspect message for refresh failure
        run_chatgpt_login_and_retry()  # mint fresh tokens, then retry once
    else:
        raise

Prevention

When it happens

Trigger: Making a chatgpt-provider call after the access token expired, where the stored refresh token is invalid, expired, revoked (user logged out elsewhere), or the server returns 5xx. The upstream status becomes the exception's status_code.

Common situations: Long-lived deployments whose stored refresh token aged out or was revoked; multiple machines sharing one auth file causing token rotation races; OpenAI auth incidents; outdated litellm sending a refresh payload the server now rejects.

Related errors


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