I have an self-hosted version of n8n:2.30.7, and a self-hosted version of chromadb/chroma:1.5.9, on azure.
Both in the same vnet, and working fine alone as they should.
But when I try to use the node “Chroma Vector Store”, it does not load any Chroma Collections, and when try to execute passing the ID, it just returns an error about “CORS” in chroma, but it is allowed to “*”
But when I try to send an HTTP request to the same endpoint, to the heartbeat endpoint for example, it returns a response, and I don’t know what to do anymore
(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)
Share the output returned by the last node
NodeOperationError: Error connecting to ChromaDB: Chroma getOrCreateCollection error: Failed to connect to chromadb. Make sure your server is running and try again. If you are running from a browser, make sure that your chromadb instance is configured to allow requests from the current origin using the CHROMA_SERVER_CORS_ALLOW_ORIGINS environment variable. at Object.getVectorStoreClient (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/@n8n+n8n-nodes-langchain@file+packages+@n8n+nodes-langchain_2c7f106572ec97ecf6e9416b33a264bd/node_modules/@n8n/n8n-nodes-langchain/nodes/vector_store/VectorStoreChromaDB/VectorStoreChromaDB.node.ts:405:10) at processTicksAndRejections (node:internal/process/task_queues:104:5) at handleLoadOperation (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/@n8n+ai-utilities@file+packages+@n8n+ai-utilities_c531a0ff6f04dcb4053a88d226097fe6/node_modules/@n8n/ai-utilities/src/utils/vector-store/createVectorStoreNode/operations/loadOperation.ts:22:22) at ExecuteContext.execute (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/@n8n+ai-utilities@file+packages+@n8n+ai-utilities_c531a0ff6f04dcb4053a88d226097fe6/node_modules/@n8n/ai-utilities/src/utils/vector-store/createVectorStoreNode/createVectorStoreNode.ts:427:19) at WorkflowExecute.executeNode (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_cf5896492347c4895f0373f4acc773d7/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1080:8) at WorkflowExecute.runNode (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_cf5896492347c4895f0373f4acc773d7/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1380:11) at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_cf5896492347c4895f0373f4acc773d7/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1842:27 at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_cf5896492347c4895f0373f4acc773d7/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:2534:11
Since both services are on the same VNet, the Chroma Vector Store node’s collection-loading requests still go browser → ChromaDB. Make sure your ChromaDB container is accessible from your public browser, not just from within the VNet. If ChromaDB is only VNet-internal (no public endpoint), the UI collection list will always fail to load — even though n8n’s own HTTP Request node (server-side) can reach it fine .
If you want ChromaDB to remain purely internal (no public exposure), a workaround is to type the collection name manually using the “Expression” mode in the Chroma Collection field instead of using the dropdown, which bypasses the browser-side listing call entirely.
When CORS is configured correctly, the response should include an access-control-allow-origin header matching the origin you sent.
If that header is missing, Chroma or the Azure layer in front of it is still not returning browser-usable CORS headers, even if heartbeat and the n8n credential test succeed. If that header is present and correct, then the problem starts to look more like a bug or compatibility gap in the Chroma node path rather than your network setup
Hi @Hugo_Fernandes
CORS isn’t in play here. The collection dropdown and the node execution both issue their Chroma requests from the n8n server process, not from your browser, so no CHROMA_*_CORS_ALLOW_ORIGINS value can affect either one. That CORS sentence is boilerplate the chromadb JS client appends to every connection failure, whatever the real cause.
A working heartbeat only proves the host is reachable. Point an HTTP Request node at the endpoint the client actually calls:
A 404 or 410 there while the heartbeat returns 200 means the client bundled in 2.30.7 and the 1.5.9 server disagree on the API surface, which is a version mismatch rather than anything configurable on your side. That status code is the useful thing to add here, since this is already with the dev team.
The CORS error you’re seeing is likely caused by how the Chroma client inside n8n connects to your server. Even though you set CORS headers in the environment variables, the Chroma Python client used by n8n’s node makes requests that may not respect those headers correctly when the server is behind a proxy or when using Docker networking. A few things to check: In your config.yaml, the keys `chroma_server_cors_allow_origins` and `CHROMA_CORS_ALLOW_ORIGINS` are not valid Chroma config keys. The correct environment variable is `CHROMA_SERVER_CORS_ALLOW_ORIGINS` (note the underscore after SERVER). Remove those lines from config.yaml and only set the environment variable in your Dockerfile or docker-compose. Make sure you’re using the full URL in the Chroma Vector Store node, including the port (e.g., `http://chroma:8000`). If both containers are on the same Docker network, use the service name instead of localhost. Try adding `CHROMA_SERVER_CORS_ALLOW_ORIGINS=[“”]` as a Docker environment variable at runtime rather than in the Dockerfile, and ensure no quotes are being escaped incorrectly. If the heartbeat endpoint works but the collection listing fails, the issue might be with the specific API path the node uses. Test with a direct HTTP request to `/api/v1/collections` to confirm the server responds. As a workaround, you can use the HTTP Request node to interact with Chroma’s REST API directly instead of the dedicated node, which gives you full control over headers and CORS handling
The 200 on v2 rules the version mismatch out. The node builds its Chroma client from the Base URL’s host, protocol and port only, and when the URL carries no explicit port it substitutes 8000. An https URL on the standard port therefore becomes port 8000 inside the node, while the credential test, Postman and the HTTP Request node all keep using 443. That is why everything except the node succeeds.
Adding :443 will not fix it either, the URL parser drops default ports and it falls back to 8000 again. The Base URL needs a port that survives parsing, so expose Chroma on a non-default port and point the credential at it:
https://your-chroma-host:8443
Worth adding the port detail to CV-34 and AI-2664, since it places the failure in how the client is constructed rather than anywhere in your Chroma config.
Yes, your Chroma instance is fine, the failure is on the node side.
App Service only accepts inbound traffic on 80 and 443, and WEBSITES_PORT only sets the port inside the container, so no Base URL pointed at that host will carry a port through. Chroma needs to sit somewhere you publish the port yourself. An Azure Container Instance in the same VNet subnet gets a private IP and can publish 8000 directly:
The nginx tunnel only needs to move off your machine to become the permanent fix. Run it as a container on the same Docker network as n8n with the config you already have, then point the credential Base URL at it:
http://chroma-proxy:8000
If n8n sits on App Service too, run it as a sidecar in the same app and use http://localhost:8000. Plain http keeps ssl off on the client and 8000 survives the URL parse, so the node reaches a real listener while Chroma stays on 443 behind App Service, with nothing changed on the Chroma side.
I had something similar before and it looked like a CORS issue, but it was actually a connection/config problem. If the HTTP Request node can reach the same Chroma endpoint, I would also check whether the Chroma Vector Store node is using the exact same base URL (including http/https and port). Also make sure n8n can access the endpoint from inside the container, not only from your browser. It may also be worth checking the Chroma server logs while the node is trying to connect, as they sometimes show a more useful error than the n8n message. Hope you find the cause.