{"record":{"id":"45426be2853ed4ed","repo":"Mintplex-Labs/anything-llm","slug":"chromadb-invalid-heartbeat-received-is-the-inst","errorCode":null,"errorMessage":"ChromaDB::Invalid Heartbeat received - is the instance online?","messagePattern":"ChromaDB::Invalid Heartbeat received - is the instance online\\?","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/vectorDbProviders/chroma/index.js","lineNumber":87,"sourceCode":"      throw new Error(\"Chroma::Invalid ENV settings\");\n\n    const client = new ChromaClient({\n      path: process.env.CHROMA_ENDPOINT, // if not set will fallback to localhost:8000\n      ...(!!process.env.CHROMA_API_HEADER && !!process.env.CHROMA_API_KEY\n        ? {\n            fetchOptions: {\n              headers: parseAuthHeader(\n                process.env.CHROMA_API_HEADER || \"X-Api-Key\",\n                process.env.CHROMA_API_KEY\n              ),\n            },\n          }\n        : {}),\n    });\n\n    const isAlive = await client.heartbeat();\n    if (!isAlive)\n      throw new Error(\n        \"ChromaDB::Invalid Heartbeat received - is the instance online?\"\n      );\n    return { client };\n  }\n\n  async heartbeat() {\n    const { client } = await this.connect();\n    return { heartbeat: await client.heartbeat() };\n  }\n\n  async totalVectors() {\n    const { client } = await this.connect();\n    const collections = await client.listCollections();\n    var totalVectors = 0;\n    for (const collectionObj of collections) {\n      const collection = await client\n        .getCollection({ name: collectionObj.name })\n        .catch(() => null);","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/20f6d3546c1938bfea1ad304f58a592dddcc5948/server/utils/vectorDbProviders/chroma/index.js#L69-L105","documentation":"During ChromaVectorDb.connect(), the client sends a heartbeat() to the Chroma server; a falsy response throws this error. It fires before credentials are exercised for data operations, so it is the first signal that CHROMA_ENDPOINT is wrong or the Chroma server process is not reachable/healthy.","triggerScenarios":"Any vector operation (connect, totalVectors, addDocumentToNamespace, namespace-stats) when Chroma is down, the endpoint URL/port is wrong, a reverse proxy strips the /api/v2 heartbeat route, or authentication headers are rejected so heartbeat returns a non-OK response.","commonSituations":"chroma server/container not started or crashed; CHROMA_ENDPOINT left at default localhost:8000 in docker where the service name should be used; Chroma v0.4+ client/server routing changes behind a proxy; firewall blocking the port.","solutions":["Start or restart Chroma: docker run -p 8000:8000 chromadb/chroma (or your compose service).","Fix CHROMA_ENDPOINT to the address actually reachable from the AnythingLLM process (http://chroma:8000 inside docker-compose, not localhost).","Verify with curl: curl http://<host>:8000/api/v2/heartbeat should return a nanosecond timestamp.","If auth is on, set both CHROMA_API_HEADER and CHROMA_API_KEY - a missing pair sends no auth and proxies may 401 the heartbeat."],"exampleFix":"# before (.env)\nVECTOR_DB=chroma\n# CHROMA_ENDPOINT unset -> defaults to localhost:8000, nothing there\n\n# after (.env)\nVECTOR_DB=chroma\nCHROMA_ENDPOINT=http://chroma:8000\nCHROMA_API_HEADER=X-Api-Key\nCHROMA_API_KEY=<secret>","handlingStrategy":"retry","validationCode":"async function chromaReachable(endpoint) {\n  try {\n    const res = await fetch(`${endpoint}/api/v2/heartbeat`, { signal: AbortSignal.timeout(3000) });\n    return res.ok;\n  } catch { return false; }\n}\nif (!(await chromaReachable(process.env.CHROMA_ENDPOINT))) throw new Error('Chroma unreachable');","typeGuard":null,"tryCatchPattern":"try {\n  await vectorDb.connect();\n} catch (e) {\n  if (/Invalid Heartbeat/i.test(e.message)) {\n    await sleep(2000); // container may still be starting\n    return vectorDb.connect();\n  }\n  throw e;\n}","preventionTips":["Use docker healthchecks and depends_on so AnythingLLM waits for Chroma.","Pin CHROMA_ENDPOINT explicitly; never rely on the localhost default inside containers.","Monitor the heartbeat route in uptime checks to catch Chroma crashes early."],"tags":["chroma","vector-db","heartbeat","connection","network"],"backgroundTag":"service-unavailable","analyzedSha":"20f6d3546c1938bfea1ad304f58a592dddcc5948","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}