xtekky/gpt4free · error · Exception

Device authorization failed {resp.status}: {resp_json}

Error message

Device authorization failed {resp.status}: {resp_json}

What it means

Raised by QwenOAuth2.startDeviceAuthorization (qwenOAuth2.py:118) when the OAuth device-authorization endpoint returns any non-200 HTTP status. The body is included, so the status + JSON usually distinguishes rate limiting (429), bad client_id (400/401), or upstream outages (5xx).

Source

Thrown at g4f/Provider/qwen/qwenOAuth2.py:118

        body_data = {
            "client_id": QWEN_OAUTH_CLIENT_ID,
            "scope": options["scope"],
            "code_challenge": options["code_challenge"],
            "code_challenge_method": options["code_challenge_method"],
        }
        async with aiohttp.ClientSession(headers={"user-agent": ""}) as session:
            async with session.post(
                QWEN_OAUTH_DEVICE_CODE_ENDPOINT,
                headers={
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Accept": "application/json",
                    "x-request-id": str(uuid.uuid4()),
                },
                data=object_to_urlencoded(body_data),
            ) as resp:
                resp_json = await resp.json()
                if resp.status != 200:
                    raise Exception(
                        f"Device authorization failed {resp.status}: {resp_json}"
                    )
                if not isDeviceAuthorizationSuccess(resp_json):
                    raise Exception(
                        f"Device authorization error: {resp_json.get('error')} - {resp_json.get('error_description')}"
                    )
                return resp_json

    async def pollDeviceToken(self, options: dict) -> Union[Dict, ErrorDataDict]:
        body_data = {
            "grant_type": QWEN_OAUTH_GRANT_TYPE,
            "client_id": QWEN_OAUTH_CLIENT_ID,
            "device_code": options["device_code"],
            "code_verifier": options["code_verifier"],
        }
        async with aiohttp.ClientSession(headers={"user-agent": ""}) as session:
            async with session.post(
                QWEN_OAUTH_TOKEN_ENDPOINT,

View on GitHub (pinned to 973504e177)

Solutions

  1. Read the embedded status: 429 → wait and retry later; 400/401 → upgrade g4f so the bundled client_id is current
  2. Upgrade g4f (pip install -U g4f)
  3. Retry after a delay — transient 5xx/429 responses resolve on their own
  4. Verify network/proxy settings allow POSTs with application/x-www-form-urlencoded bodies
Defensive patterns

Strategy: retry

Try / catch

try:
    resp = await oauth.startDeviceAuthorization({"scope": "openid"})
except Exception as exc:
    msg = str(exc)
    if " 429" in msg:
        await asyncio.sleep(60)  # rate limited; back off and retry
        resp = await oauth.startDeviceAuthorization({"scope": "openid"})
    else:
        raise

Prevention

When it happens

Trigger: POST to QWEN_OAUTH_DEVICE_CODE_ENDPOINT returning non-200: rate-limited device flows (429), invalid client_id/grant_type in body_data, expired x-request-id handling, or Qwen auth service downtime.

Common situations: Starting Qwen login too frequently from one IP; g4f version carrying an outdated QWEN_OAUTH_CLIENT_ID after Qwen rotated it; transient 5xx on the Qwen identity service; corporate proxy stripping form-urlencoded bodies.

Related errors


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/7814acb86d1d8a5e. Report an issue: GitHub.