affaan-m/ECC · warning · RateLimitError
{msg}
Error message
{msg} What it means
OllamaProvider.generate() raises RateLimitError when the exception message contains '429' or 'rate_limit'. Ollama is local and has no per-key quota, so this typically fires when OLLAMA_NUM_PARALLEL or OLLAMA_MAX_LOADED_MODELS is exceeded (older Ollama defaulted NUM_PARALLEL to 1), or when a reverse proxy/gateway in front of Ollama enforces 429s.
Source
Thrown at src/llm/providers/ollama.py:106
id=tc.get("id", ""),
name=tc.get("function", {}).get("name", ""),
arguments=tc.get("function", {}).get("arguments", {}),
)
for tc in result["message"]["tool_calls"]
]
return LLMOutput(
content=content,
tool_calls=tool_calls,
model=model,
stop_reason=result.get("done_reason"),
)
except Exception as e:
msg = str(e)
if "401" in msg or "connection" in msg.lower():
raise AuthenticationError(f"Ollama connection failed: {msg}", provider=ProviderType.OLLAMA) from e
if "429" in msg or "rate_limit" in msg.lower():
raise RateLimitError(msg, provider=ProviderType.OLLAMA) from e
if "context" in msg.lower() and "length" in msg.lower():
raise ContextLengthError(msg, provider=ProviderType.OLLAMA) from e
raise
def list_models(self) -> list[ModelInfo]:
return self._models.copy()
def validate_config(self) -> bool:
return bool(self.base_url)
def get_default_model(self) -> str:
return self.default_model
View on GitHub (pinned to 01e15490f0)
Solutions
- Serialize Ollama calls or raise OLLAMA_NUM_PARALLEL in the server config.
- Reduce concurrency of the calling code.
- If behind a proxy, raise its rate limit.
- Retry with exponential backoff on RateLimitError.
Example fix
// before
output = provider.generate(llm_input)
// after
import time
from llm.core.interface import RateLimitError
for attempt in range(4):
try:
output = provider.generate(llm_input)
break
except RateLimitError:
if attempt == 3:
raise
time.sleep(2 ** attempt) Defensive patterns
Strategy: retry
Validate before calling
import os, httpx
def ollama_has_capacity(base_url: str) -> bool:
# OLLAMA_NUM_PARALLEL defaults vary; this is a liveness check only
try:
return httpx.get(f"{base_url.rstrip('/')}/api/tags", timeout=5).status_code == 200
except Exception:
return False Type guard
from llm.core.interface import RateLimitError
def is_ollama_rate_limit(exc: BaseException) -> bool:
return isinstance(exc, RateLimitError) Try / catch
import time
from llm.core.interface import RateLimitError
for attempt in range(4):
try:
output = provider.generate(llm_input)
break
except RateLimitError:
if attempt == 3:
raise
time.sleep(2 ** attempt) Prevention
- Serialize Ollama calls or raise OLLAMA_NUM_PARALLEL on the server.
- Don't fan out parallel requests to a single local Ollama instance.
- If behind a proxy, size its rate limit to expected throughput.
When it happens
Trigger: More concurrent requests than OLLAMA_NUM_PARALLEL; a gateway/proxy in front of Ollama returning 429; an Ollama error whose text happens to contain 'rate_limit'.
Common situations: Parallel agent loops hitting a single local Ollama; OLLAMA_NUM_PARALLEL left at default; Ollama routed through nginx with rate limiting; a version change adding rate-limit-style errors for a busy GPU.
Related errors
- Ollama connection failed: {msg}
- {msg}
- {msg}
- Issue #${issue.number} is already claimed by ${state.owner |
- ${label} must remain a regular, non-symlink file while it is
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/9abc08756320e104.
Report an issue: GitHub.