xtekky/gpt4free · error · MissingAuthError

Response {response.status}: Invalid API key

Error message

Response {response.status}: Invalid API key

What it means

Raised when the upstream returns HTTP 400 whose body contains 'API key not valid'. g4f pattern-matches this Google/Google-AI-Studio style error and rewrites it to MissingAuthError, so a bad-request auth failure is catchable as an auth problem rather than a generic 400.

Source

Thrown at g4f/requests/raise_for_status.py:81

                "text/html"
            ) or message.lower().startswith("<!DOCTYPE".lower())
    if message is None or is_html:
        if response.status == 520:
            message = "Unknown error (Cloudflare)"
    if response.status in (429, 402):
        raise RateLimitError(f"Response {response.status}: {message}")
    if response.status == 401:
        raise MissingAuthError(f"Response {response.status}: {message}")
    if response.status == 403 and is_cloudflare(message):
        raise CloudflareError(f"Response {response.status}: Cloudflare detected")
    elif response.status == 403 and (is_openai(message) or is_lmarena(message)):
        raise MissingAuthError(f"Response {response.status}: OpenAI Bot detected")
    elif response.status == 502:
        raise ResponseStatusError(f"Response {response.status}: Bad Gateway")
    elif response.status == 504:
        raise RateLimitError(f"Response {response.status}: Gateway Timeout ")
    elif response.status == 400 and "API key not valid" in message:
        raise MissingAuthError(f"Response {response.status}: Invalid API key")
    else:
        raise ResponseStatusError(
            f"Response {response.status}: {'HTML content' if is_html else message}"
        )


def raise_for_status(
    response: Union[Response, StreamResponse, ClientResponse, RequestsResponse],
    message: str = None,
):
    if hasattr(response, "status"):
        return raise_for_status_async(response, message)
    if response.ok:
        return
    is_html = False
    if message is None:
        is_html = response.headers.get("content-type", "").startswith(
            "text/html"

View on GitHub (pinned to 973504e177)

Solutions

  1. Regenerate the API key in the provider console and set the correct env var/argument.
  2. Confirm the key matches the provider (no cross-vendor keys).
  3. Test the key with a direct curl call to the provider API.
  4. Check key restrictions (model access, referrer/IP allowlists) in the provider dashboard.
Defensive patterns

Strategy: validation

Validate before calling

import re
KEY_RE = re.compile(r'^[A-Za-z0-9_\-]{20,}$')
def key_looks_valid(key: str | None) -> bool:
    return bool(key and KEY_RE.match(key.strip()))

assert key_looks_valid(os.environ.get('GEMINI_API_KEY'))

Type guard

from g4f.errors import MissingAuthError
def is_invalid_key(err: BaseException) -> bool:
    return isinstance(err, MissingAuthError) and 'Invalid API key' in str(err)

Try / catch

from g4f.errors import MissingAuthError
try:
    result = await client.chat.completions.async_create(...)
except MissingAuthError as e:
    if 'Invalid API key' in str(e):
        key = rotate_or_regen_key()  # fetch a fresh key, then retry once
        result = await client.chat.completions.async_create(..., api_key=key)
    else:
        raise

Prevention

When it happens

Trigger: Using a Gemini/Google-style provider through g4f with a malformed, revoked, or wrong-project API key; the API rejects the key at validation time with 400 instead of 401.

Common situations: Copied key with typos or truncated; key deleted in Google AI Studio; using an OpenAI key against a Google endpoint or vice versa; free-tier key restricted from the requested model.

Understand the failure class

Related errors


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