chroma-core/chroma · error · RuntimeError
Request to Chroma Cloud API timed out after 60 seconds
Error message
Request to Chroma Cloud API timed out after 60 seconds
What it means
The /embed_sparse request is sent with timeout=60; if httpx raises TimeoutException (connect/read/write/pool timeout) the function converts it to RuntimeError with this fixed message. It signals the API endpoint did not answer in time, not that your inputs were wrong.
Solutions
- Retry with exponential backoff — timeouts are frequently transient.
- Reduce batch size so each request finishes well under 60s.
- Run fewer concurrent embedding calls or share one EF instance across threads instead of many.
- If it persists, check network egress and Chroma Cloud status.
Example fix
# before
vecs = ef(big_batch) # RuntimeError: timed out after 60 seconds
# after: smaller batches + retry
import time
vecs = []
for i in range(0, len(docs), 64):
for attempt in range(3):
try:
vecs += ef(docs[i:i + 64])
break
except RuntimeError as e:
if "timed out" not in str(e) or attempt == 2:
raise
time.sleep(2 ** attempt) Defensive patterns
Strategy: retry
Validate before calling
# keep batches small enough that a request reliably finishes < 60s BATCH = 64 assert len(batch) <= BATCH
Try / catch
import time
def embed_retry(ef, texts, retries=3):
for attempt in range(retries + 1):
try:
return ef(texts)
except RuntimeError as e:
if "timed out" not in str(e) or attempt == retries:
raise
time.sleep(2 ** attempt) Prevention
- Embed in modest batches (e.g. 32-128 texts) instead of one huge call.
- Bound concurrency to avoid starving the shared httpx client pool.
- Wrap embed calls in retry-with-backoff tuned to the fixed 60s client timeout.
When it happens
Trigger: Calling ef(texts) with large batches of texts where the server takes more than 60s to return sparse embeddings; slow or saturated networks; Chroma Cloud latency spikes; connection pool starvation from many concurrent EF instances.
Common situations: Bulk ingestion jobs embedding thousands of documents per call; running many workers against the same endpoint during load; mobile/high-latency networks; concurrent requests exhausting the shared httpx.Client pool.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Failed to get embeddings from Chroma Cloud API
- Failed to get embeddings from Chroma Cloud API: HTTP
- The httpx python package is not installed. Please install…
- Unexpected error calling Chroma Cloud API
- Updating ' ' is not supported for chroma-cloud-splade
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/06d34a47a4c488f4.
Report an issue: GitHub.
Appendix: source
Thrown at chromadb/utils/embedding_functions/chroma_cloud_splade_embedding_function.py:108
"texts": list(input),
"task": "",
"target": "",
"fetch_tokens": "true" if self.include_tokens is True else "false",
}
try:
import httpx
response = self._session.post(self._api_url, json=payload, timeout=60)
response.raise_for_status()
json_response = response.json()
return self._parse_response(json_response)
except httpx.HTTPStatusError as e:
raise RuntimeError(
f"Failed to get embeddings from Chroma Cloud API: HTTP {e.response.status_code} - {e.response.text}"
)
except httpx.TimeoutException:
raise RuntimeError("Request to Chroma Cloud API timed out after 60 seconds")
except httpx.HTTPError as e:
raise RuntimeError(f"Failed to get embeddings from Chroma Cloud API: {e}")
except Exception as e:
raise RuntimeError(f"Unexpected error calling Chroma Cloud API: {e}")
def _parse_response(self, response: Any) -> SparseVectors:
"""
Parse the response from the Chroma Cloud Sparse Embedding API.
"""
raw_embeddings = response["embeddings"]
# Normalize each sparse vector (sort indices and validate)
normalized_vectors: SparseVectors = []
for emb in raw_embeddings:
# Handle both dict format and SparseVector format
if isinstance(emb, dict):
indices = emb.get("indices", [])
values = emb.get("values", [])View on GitHub (pinned to aecdd12c8a)