invoke-ai/InvokeAI · error · ExternalProviderRateLimitError
Rate limit exceeded after all retries
Error message
Rate limit exceeded after all retries
What it means
ExternalProviderRateLimitError raised by _generate_with_retry after the request was retried _MAX_RETRIES times and the external provider kept returning rate-limit (HTTP 429) responses. Indicates sustained throttling by the upstream provider, not a client bug.
Source
Thrown at invokeai/app/services/external_generation/external_generation_default.py:89
def _generate_with_retry(
self, provider: ExternalProvider, request: ExternalGenerationRequest
) -> ExternalGenerationResult:
for attempt in range(self._MAX_RETRIES):
try:
return provider.generate(request)
except ExternalProviderRateLimitError as exc:
if attempt == self._MAX_RETRIES - 1:
raise
delay = min(exc.retry_after or self._DEFAULT_RETRY_DELAY, self._MAX_RETRY_DELAY)
self._logger.warning(
"Rate limited by %s (attempt %d/%d), retrying in %.0fs",
request.model.provider_id,
attempt + 1,
self._MAX_RETRIES,
delay,
)
time.sleep(delay)
raise ExternalProviderRateLimitError("Rate limit exceeded after all retries")
def get_provider_statuses(self) -> dict[str, ExternalProviderStatus]:
return {provider_id: provider.get_status() for provider_id, provider in self._providers.items()}
def _validate_request(self, request: ExternalGenerationRequest) -> None:
capabilities = request.model.capabilities
self._logger.debug(
"Validating external request provider=%s model=%s mode=%s supported=%s",
request.model.provider_id,
request.model.provider_model_id,
request.mode,
capabilities.modes,
)
if request.mode not in capabilities.modes:
raise ExternalProviderCapabilityError(f"Mode '{request.mode}' is not supported by {request.model.name}")
View on GitHub (pinned to 0b6a024f2f)
Solutions
- Wait and retry later once the provider's rate-limit window resets
- Upgrade the provider API key tier or raise its quota
- Reduce request rate: add client-side throttling/queuing between generation requests
- Switch to a different configured provider for this workload
- Increase _MAX_RETRIES / backoff delay if sustained bursts are expected
Example fix
// before: tight loop of generate() calls
for prompt in prompts:
service.generate(make_request(prompt))
// after: throttle client-side
for prompt in prompts:
service.generate(make_request(prompt))
time.sleep(5) # stay under provider RPM Defensive patterns
Strategy: retry
Validate before calling
# No pre-call check possible for server-side rate limits; pace calls proactively
MIN_INTERVAL = 5.0
last = [0.0]
def pace():
wait = MIN_INTERVAL - (time.monotonic() - last[0])
if wait > 0: time.sleep(wait)
last[0] = time.monotonic() Type guard
None
Try / catch
try:
result = service.generate(request)
except ExternalProviderRateLimitError:
time.sleep(60) # wait out the provider's rate window
result = service.generate(request) # or fail over to another provider Prevention
- Throttle/queue outgoing generation requests under the provider's RPM/TPM limits
- Use a paid/higher-tier API key for batch workloads
- Spread long batch jobs with delays; avoid bursts from parallel workers sharing one key
- Monitor provider usage dashboards and alert before hitting quotas
When it happens
Trigger: generate() -> _generate_with_retry exhausts all retries with exponential backoff because every call to the external provider API returns a rate-limit response.
Common situations: Shared/free-tier API keys hitting provider quotas; batch jobs issuing many generation requests back-to-back; multiple users on the same API key; provider-side capacity limits during peak hours.
Related errors
- Unexpected error while retrying queue items: {e}
- {label} network error: {exc}
- {label} failed after retries: {last_exc}
- Gemini rate limit exceeded. {f'Retry after {retry_after:.0f}
- Gemini request failed with status {response.status_code} for
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/acbcc711c619dc1c.
Report an issue: GitHub.