chroma-core/chroma · critical · ValueError
Downloaded file {fname} does not match expected SHA256 hash.
Error message
Downloaded file {fname} does not match expected SHA256 hash. Corrupted download or malicious file. What it means
ONNXMiniLM_L6_V2 downloads the all-MiniLM-L6-v2 ONNX model into ~/.cache/chroma/onnx_models/all-MiniLM-L6-v2/ and verifies its SHA256 against the pinned constant 913d7300...a16ec3. On mismatch the file is deleted (os.remove) and ValueError is raised; the @retry decorator on _download re-attempts up to 3 times with 1-3s random waits specifically when the message contains "does not match expected SHA256", so this error surfaces only after repeated corrupted downloads. It guards both truncated downloads and supply-chain tampering.
Source
Thrown at chromadb/utils/embedding_functions/onnx_mini_lm_l6_v2.py:122
fname: The path to save the model to.
chunk_size: The chunk size to use when downloading.
"""
with httpx.stream("GET", url) as resp:
total = int(resp.headers.get("content-length", 0))
with open(fname, "wb") as file, self.tqdm(
desc=str(fname),
total=total,
unit="iB",
unit_scale=True,
unit_divisor=1024,
) as bar:
for data in resp.iter_bytes(chunk_size=chunk_size):
size = file.write(data)
bar.update(size)
if not _verify_sha256(fname, self._MODEL_SHA256):
os.remove(fname)
raise ValueError(
f"Downloaded file {fname} does not match expected SHA256 hash. Corrupted download or malicious file."
)
# Use pytorches default epsilon for division by zero
# https://pytorch.org/docs/stable/generated/torch.nn.functional.normalize.html
def _normalize(self, v: npt.NDArray[np.float32]) -> npt.NDArray[np.float32]:
"""
Normalize a vector.
Args:
v: The vector to normalize.
Returns:
The normalized vector.
"""
norm = np.linalg.norm(v, axis=1)
# Handle division by zero
norm[norm == 0] = 1e-12View on GitHub (pinned to aecdd12c8a)
Solutions
- Check network stability and retry after the bad file has been auto-removed; if a stale corrupt file lingers, clear the cache: rm -rf ~/.cache/chroma/onnx_models/all-MiniLM-L6-v2
- If behind a proxy, bypass or fix it (configure HTTP(S)_PROXY properly, disable TLS interception for the download host) so the binary arrives intact
- Pre-download the model manually on a trusted machine, verify its SHA256 equals 913d7300ceae3b2dbc2c50d1de4baacab4be7b9380491c27fab7418616a16ec3, and place it at ~/.cache/chroma/onnx_models/all-MiniLM-L6-v2/onnx.tar.gz (the DOWNLOAD_PATH) on the target machine
- If the hash mismatch persists on a known-good network, treat it as a potential tampering signal: do not disable verification, investigate the source
Example fix
// shell — clear a corrupted cache and retry on a stable network rm -rf ~/.cache/chroma/onnx_models/all-MiniLM-L6-v2 python -c "from chromadb.utils.embedding_functions.onnx_mini_lm_l6_v2 import ONNXMiniLM_L6_V2; ONNXMiniLM_L6_V2()"
Defensive patterns
Strategy: retry
Validate before calling
import hashlib
from pathlib import Path
EXPECTED = "913d7300ceae3b2dbc2c50d1de4baacab4be7b9380491c27fab7418616a16ec3"
model_dir = Path.home() / ".cache" / "chroma" / "onnx_models" / "all-MiniLM-L6-v2"
for f in model_dir.glob("*") if model_dir.exists() else []:
h = hashlib.sha256(f.read_bytes()).hexdigest()
if f.name.endswith(".tar.gz") and h != EXPECTED:
f.unlink() # remove corrupt cache so Chroma re-downloads
# construction now downloads fresh if needed Try / catch
from tenacity import retry, retry_if_exception, stop_after_attempt, wait_exponential
@retry(reraise=True, stop=stop_after_attempt(3),
retry=retry_if_exception(lambda e: isinstance(e, ValueError) and "SHA256" in str(e)),
wait=wait_exponential(min=2, max=30))
def build_ef():
return ONNXMiniLM_L6_V2()
# note: Chroma already retries 3x internally; add outer retries only across longer intervals after clearing the cache dir Prevention
- On flaky networks, pre-download the model once, verify its SHA256, and bake ~/.cache/chroma/onnx_models into the image
- Fix proxy/TLS-intercepting middleboxes rather than working around the integrity check
- Keep ~/.cache on a disk with free space; interrupted writes produce checksum failures
- Never disable or patch out the SHA256 check — a persistent mismatch is a security signal
When it happens
Trigger: Flaky network/proxy that truncates the ~80MB download (mismatch survives 3 retries); a MITM proxy or antivirus rewriting the file; a partially-written cache file from a previously killed process (note the code removes the bad file before raising, so a stale corrupt file alone is cleaned up); a compromised or hijacked download host serving a different binary.
Common situations: Corporate proxies with aggressive content inspection; hotel/public wifi drops mid-download; full or flaky disk in ~/.cache; CI runners with unreliable egress; the security-sensitive case where the hash genuinely doesn't match (treat as incident).
Related errors
- Preferred providers must be a list of strings
- Preferred providers must be unique
- The onnxruntime python package is not installed. Please inst
- The tokenizers python package is not installed. Please insta
- The tqdm python package is not installed. Please install it
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/11cb5508ddf8d5e3.
Report an issue: GitHub.