invoke-ai/InvokeAI · warning · ExternalProviderRateLimitError

Gemini rate limit exceeded. {f'Retry after {retry_after:.0f}

Error message

Gemini rate limit exceeded. {f'Retry after {retry_after:.0f}s.' if retry_after else 'Please try again later.'}

What it means

ExternalProviderRateLimitError raised by GeminiProvider.generate when Google's Gemini API responds with HTTP 429. The provider parses the Retry-After header (via _parse_retry_after) and includes a human-readable 'Retry after Ns' hint when available; otherwise it says 'Please try again later.' The retry_after value is attached to the exception for programmatic backoff.

Source

Thrown at invokeai/app/services/external_generation/providers/gemini.py:116

        payload: dict[str, object] = {
            "systemInstruction": {"parts": [{"text": system_instruction}]},
            "contents": [{"role": "user", "parts": request_parts}],
            "generationConfig": generation_config,
        }
        if "thinking_level" in opts:
            payload["thinkingConfig"] = {"thinkingLevel": opts["thinking_level"].upper()}

        response = requests.post(
            endpoint,
            params={"key": api_key},
            json=payload,
            timeout=120,
        )

        if not response.ok:
            if response.status_code == 429:
                retry_after = _parse_retry_after(response.headers.get("retry-after"))
                raise ExternalProviderRateLimitError(
                    f"Gemini rate limit exceeded. {f'Retry after {retry_after:.0f}s.' if retry_after else 'Please try again later.'}",
                    retry_after=retry_after,
                )
            raise ExternalProviderRequestError(
                f"Gemini request failed with status {response.status_code} for model '{model_id}': {response.text}"
            )

        data = response.json()
        if not isinstance(data, dict):
            raise ExternalProviderRequestError("Gemini response payload was not a JSON object")
        images: list[ExternalGeneratedImage] = []
        text_parts: list[str] = []
        finish_messages: list[str] = []
        candidates = data.get("candidates")
        if not isinstance(candidates, list):
            raise ExternalProviderRequestError("Gemini response payload missing candidates")
        for candidate in candidates:
            if not isinstance(candidate, dict):

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Catch ExternalProviderRateLimitError and wait at least e.retry_after seconds before retrying (exponential backoff if unset).
  2. Reduce request rate: serialize generations, add delays, or lower candidateCount/num_images per request.
  3. Upgrade the Google AI Studio plan or request a quota increase for the generateContent/image quota.
  4. Rotate to a different API key or region if multiple clients share one quota.

Example fix

// before: blind retry amplifies 429s
while True:
    try:
        return provider.generate(request)
    except Exception:
        continue
// after: honor Retry-After from the typed rate-limit error
import time
try:
    return provider.generate(request)
except ExternalProviderRateLimitError as e:
    time.sleep(e.retry_after if e.retry_after else 30)
    return provider.generate(request)
Defensive patterns

Strategy: retry

Try / catch

import time
for attempt in range(3):
    try:
        return provider.generate(request)
    except ExternalProviderRateLimitError as e:
        wait = e.retry_after if e.retry_after else 2 ** attempt * 5
        time.sleep(wait)
raise  # give up after 3 attempts

Prevention

When it happens

Trigger: POST to {base_url}/models/{model_id}:generateContent returns status 429. Happens when per-minute/per-day quotas for the API key are exhausted, free-tier RPM limits are hit, or the model (e.g. image-generation models) has stricter quotas than the account allows.

Common situations: Batch generating many images in a loop; free-tier Gemini key with low RPM; multiple InvokeAI clients sharing one API key; image models with very low quota; burst of retrying clients amplifying load.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/b3f409c2a8b5cc4b. Report an issue: GitHub.