Resolve "ChromaDB collection does not exist"
Quick answer
"Collection does not exist" in ChromaDB has two dominant causes. First, get_collection() requires the collection to already exist — use get_or_create_collection() instead, and call list_collections() to check the exact name. Second, an ephemeral client (chromadb.Client or EphemeralClient) keeps data in memory and loses it between runs, so use PersistentClient(path=...) and always reopen the exact same path you created it with.
You built a vector store, added documents, and now:
chromadb.errors.InvalidCollectionException: Collection my_docs does not exist.Nine times out of ten this is one of two things, and they're easy to mix up. Either
you asked ChromaDB to open a collection that was never created (a
get_collection vs get_or_create problem), or the collection was created but
never saved to disk (an ephemeral-client problem). The error message is the
same for both, which is why people fix the wrong one.
This guide separates them, gives you the two one-line fixes, and then covers the subtler cause behind persistent-client failures: a path mismatch that quietly points you at an empty database.
Quick Answer
Two dominant causes. (1) get_collection() requires the collection to exist —
use get_or_create_collection() and list_collections() to check the name.
(2) An ephemeral client (chromadb.Client / EphemeralClient) keeps data in
memory and loses it between runs — use PersistentClient(path=...) and always
reopen the exact same path.
TL;DR
get_collection()raises if missing → useget_or_create_collection().- Ephemeral client = in-memory → data gone between runs; use
PersistentClient(path=...). - Persistent but still missing? → you opened a different path. Use an absolute one.
- Check reality with
client.list_collections(). - Names are case-sensitive —
MyDocs≠mydocs. - Major version upgrade (0.4 → 0.5+) changed storage — migrate, don't just upgrade.
Which of the Two Is It?
Answer two questions and you're done:
- Are you calling
get_collectionorget_or_create_collection? The first demands the collection already exist. - Is your client ephemeral or persistent? Ephemeral never saved anything; persistent must open the same path it wrote to.
Cause 1: get_collection on Something That Isn't There
get_collection() is strict — it opens an existing collection and raises if it's
missing. get_or_create_collection() opens it if present, creates it if not:
import chromadb
client = chromadb.PersistentClient(path="./chroma_db")
# ❌ raises if 'my_docs' was never created
col = client.get_collection("my_docs")
# ✅ opens it, or creates it on first run — never raises 'does not exist'
col = client.get_or_create_collection("my_docs")Use get_or_create_collection unless you want a hard failure when the
collection is absent. Before assuming a bug, see what's actually there:
print(client.list_collections()) # names actually in this databaseName mismatch hides here too. Collection names are case-sensitive and exact.
get_collection("MyDocs") fails if you created my_docs. list_collections()
shows the true names — copy from there rather than retyping.
Cause 2: An Ephemeral Client That Never Persisted
This is the one that confuses people most: the code works within a single run, then "loses" the collection on the next run. That's because the client is in-memory.
import chromadb
# ❌ ephemeral — data lives in RAM, gone when the process exits
client = chromadb.Client() # same as EphemeralClient()
client.create_collection("my_docs") # works now...
# ...next run: Collection my_docs does not exist
# ✅ persistent — writes to disk, survives restarts
client = chromadb.PersistentClient(path="./chroma_db")
col = client.get_or_create_collection("my_docs")chromadb.Client()/EphemeralClient()→ RAM only. Great for tests, wrong for anything you reopen.PersistentClient(path=...)→ writes a SQLite store to disk. This is what you want for a real vector store.
On modern ChromaDB you don't call .persist() anymore — PersistentClient
writes automatically. If you're following an old tutorial that calls
client.persist(), that method was removed; switching to PersistentClient is
the fix, not adding the call back.
Cause 3: Persistent, but the Wrong Path
If you're already on PersistentClient and still get the error, it's almost
always a path mismatch — you created the database in one place and opened
another. The most common traps:
- A relative path (
"./chroma_db") resolves against the current working directory, which differs between your script, a notebook, and a cron job. - Two services use different paths and each sees an empty database.
- A container mounts the volume at a different location than where data was written.
Use an absolute, single source of truth:
import os, chromadb
CHROMA_PATH = os.path.abspath("./chroma_db") # pin it once
print("Chroma path:", CHROMA_PATH)
client = chromadb.PersistentClient(path=CHROMA_PATH)
print(client.list_collections()) # is your collection here?If list_collections() is empty at this path, your data is somewhere else —
find the directory that actually contains chroma.sqlite3 and point at it.
Framework Notes
LangChain
The LangChain Chroma wrapper has the same two levers — collection_name and
persist_directory. Mismatch either and you get "does not exist":
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
vs = Chroma(
collection_name="my_docs", # must match what you created
persist_directory="./chroma_db", # must match the write path
embedding_function=OpenAIEmbeddings(),
)Create it once with Chroma.from_documents(..., persist_directory=..., collection_name=...),
then reopen with the same two values. For a ValidationError from the
LangChain side, see resolving LangChain ValidationError.
Client/server mode (HttpClient)
When talking to a Chroma server, the collection lives on the server, not your
process. "Does not exist" here usually means you're on a different tenant or
database, or the server was restarted without a persistent volume. Confirm
with client.list_collections() against that server.
Version Compatibility
| Chroma era | Persistence | Notes |
|---|---|---|
| 0.3.x | duckdb+parquet (legacy) | Old Settings(persist_directory=...) style |
| 0.4.x | SQLite + .persist() | .persist() still present |
| 0.5.x+ | SQLite, auto-persist | .persist() removed; use PersistentClient |
Crossing a major boundary changes the on-disk format. Upgrading without migrating,
or pointing a new client at an old store, can make collections look missing. Pin
your chromadb version and migrate deliberately.
Verification Steps
list_collections()shows your collection at the path you're opening:
import chromadb
client = chromadb.PersistentClient(path="/abs/path/chroma_db")
print([c.name for c in client.list_collections()]) # ['my_docs']- A
get_or_create_collection+count()round-trip works after a restart:
col = client.get_or_create_collection("my_docs")
print(col.count()) # > 0 means data persisted- The path you print matches everywhere the DB is opened.
chroma.sqlite3exists under that directory.- In server mode, the collection appears in
list_collections()against the server.
Green state: after a full restart, PersistentClient at your fixed absolute
path lists the collection and count() returns your documents. That proves it
truly persisted.
Prevention
- Default to
get_or_create_collection()unless you need a hard miss. - Use
PersistentClientwith an absolute path for anything you reopen. - Define the path and collection name as constants, imported everywhere.
-
list_collections()at startup and log what's there. - Keep
collection_nameandpersist_directoryidentical across services. - Pin the
chromadbversion; migrate on purpose, not by accident. - Mount persistent volumes at a stable path in Docker/K8s.
Troubleshooting Matrix
| Symptom | Likely cause | Fix |
|---|---|---|
| Fails the first time | get_collection on a new name | Use get_or_create_collection |
| Works in-run, gone next run | Ephemeral client | Use PersistentClient(path=...) |
| Persistent but empty | Wrong / relative path | Use one absolute path |
| Wrong name / case | Typo | Copy name from list_collections() |
| Missing after upgrade | Storage format change | Pin version, migrate the store |
| Missing in Docker | Volume path mismatch | Mount at the same path |
Missing via HttpClient | Wrong tenant/database or no volume | Check server + persistence |
Tutorial calls .persist() | Removed API | Switch to PersistentClient |
Related Guides
- Fix SentenceTransformer model download failed
- Resolve LangChain ValidationError
- Fix OpenAI RateLimitError (429)
- Resolve Hugging Face 401 Unauthorized
- Designing a durable RAG vector store
External References
- Chroma documentation
- Chroma — Clients (persistent vs ephemeral)
- Chroma — Collections API
- LangChain — Chroma integration
FAQs
Is chromadb.Client() the same as EphemeralClient()?
Yes — chromadb.Client() creates an ephemeral, in-memory client. Neither persists
to disk. For anything you reopen later, use PersistentClient(path=...).
Do I still need .persist()?
No. On modern Chroma, PersistentClient writes automatically. .persist() was
removed; code that calls it should switch to PersistentClient rather than trying
to restore the method.
Why does it work in my notebook but not my script?
Usually a relative-path difference. The notebook and the script run from different
working directories, so "./chroma_db" resolves to different folders. Use an
absolute path in both.
Can two processes share one persistent Chroma path?
For concurrent writers, run Chroma in server mode (HttpClient against a Chroma
server) rather than pointing multiple PersistentClient processes at the same
directory. A single persistent path is designed for one writer.
How do I recover a collection I think I lost?
Point a PersistentClient at the directory containing chroma.sqlite3 and call
list_collections(). If it's listed, it was a path/name issue, not data loss. If
the directory has no chroma.sqlite3, the data was never persisted.
Key takeaways
- •get_collection() fails if the collection isn't there — use get_or_create_collection() to create-or-open safely.
- •An ephemeral client stores data in memory and loses it between runs; use PersistentClient(path=...) to keep it.
- •A persistent client must reopen the exact same path used at creation — a different path or working directory means an empty database.
- •Call client.list_collections() to see what actually exists and confirm the name and case.
- •Collection names are case-sensitive and exact — a typo reads as 'does not exist'.
- •Crossing a major Chroma version (0.4 to 0.5+) changed persistence; upgrading without migrating can hide old collections.
Frequently asked questions
Why does ChromaDB say my collection does not exist?
Because ChromaDB couldn't find a collection with that name in the database you're connected to. The two common reasons are calling get_collection() when it was never created, and using an ephemeral in-memory client whose data vanished between runs. Use get_or_create_collection() and a PersistentClient with a fixed path.
What's the difference between get_collection and get_or_create_collection?
get_collection() only opens an existing collection and raises if it isn't found. get_or_create_collection() opens it if it exists and creates it otherwise, so it never raises 'does not exist'. Use get_or_create_collection() unless you specifically want to fail when the collection is missing.
Why does my Chroma collection disappear between runs?
Because you used an ephemeral client — chromadb.Client() or chromadb.EphemeralClient() — which stores everything in memory. When the process ends, the data is gone. Switch to chromadb.PersistentClient(path='./chroma_db'), which writes to disk and survives restarts.
I used PersistentClient but the collection is still missing — why?
Almost always a path mismatch. You created the database at one path and opened a different one, or you ran from a different working directory so a relative path resolved elsewhere. Use an absolute path, keep it identical everywhere, and call list_collections() to confirm what's in that database.
How do I list existing ChromaDB collections?
Call client.list_collections(). It returns the collections in the database you're connected to, so you can confirm the exact name and case, and verify you're pointed at the right persistent path. If the list is empty, your data was never persisted or you're on the wrong path.
Did upgrading ChromaDB break my collections?
Possibly. Chroma changed its storage between major versions (for example 0.4 to 0.5), and the old .persist() call and legacy backends were removed. Upgrading without migrating the on-disk database, or pointing a new version at an old store, can make collections appear missing. Pin versions and migrate deliberately.
Software Engineering Leader & Technical Author · Updated July 24, 2026