Analysis
September 5, 2026
8 min read
Maxime Dalessandro

CVE-2026-85664: Chroma's unbounded HNSW index parameters

A collection-create request could size Chroma's HNSW index without limits and exhaust server memory. Postgres closed this failure class decades ago.

#Chroma#CVE-2026-85664#HNSW#vector database#database reliability#AI agents#pgvector

TL;DR. CVE-2026-85664 reports that Chroma 1.5.9 accepts collection-create requests without validating upper bounds on the HNSW parameters max_neighbors, ef_construction, and ef_search. An unauthenticated caller can supply arbitrarily large values and exhaust server memory when the index is later built during compaction. The bug class is CWE-770, allocation of resources without limits, and it is one of the oldest failure modes in database operations. The interesting part is the contrast: pgvector builds the same index type under an explicit memory budget and degrades to a slower build when it runs out. One design treats a caller-supplied number as a resource claim to be bounded; the other cashed it unchecked.

A denial-of-service flaw disclosed this week against Chroma, tracked as CVE-2026-85664, needs no exploit cleverness at all. The advisory describes Chroma 1.5.9 failing to validate maximum bounds on three HNSW index parameters accepted in collection-create requests: max_neighbors, ef_construction, and ef_search. A network-reachable caller, with no authentication and no user interaction, can create a collection whose index configuration is sized to exceed the machine, and the server pays for it when the index gets built. Vector stores have spent two years moving from prototype dependency to production infrastructure under AI agent stacks, and this is the kind of bug that marks the transition: an ordinary database-reliability failure, arriving in a young engine, dressed as an AI-era security advisory.

Three numbers that size an allocation

HNSW parameters are capacity multipliers, which is what makes leaving them unbounded expensive. max_neighbors (the M of the original paper) sets how many graph edges each inserted vector may hold per layer, so index memory grows with it linearly at minimum. ef_construction sizes the candidate list the build phase keeps while wiring each new vector into the graph: larger values mean better recall and proportionally more working memory and CPU per insert. ef_search sizes the same list at query time. These are real tuning knobs with legitimate ranges, and every serious HNSW deployment adjusts them. The defaults in pgvector, for scale, are 16, 64, and 40.

The advisory's mechanism has one detail worth dwelling on: the memory exhaustion lands during index compaction, not at request time. Chroma buffers writes and builds index segments asynchronously, so the create request that carries the hostile parameters returns successfully. The allocation it describes comes due later, on a background path, when the compactor materializes the index those parameters define. That gap between accepting a value and paying for it is what turns a missing validation into an operational incident: the request that killed the server is not in the error logs next to the crash, and nothing on the failing path names the collection that caused it. Anyone who has chased a Postgres out-of-memory kill back to one bad query knows the shape of that investigation, except that here the "query" ran minutes or hours earlier and succeeded.

Relational databases spent decades bounding caller input

The CWE classification on this advisory, CWE-770, allocation of resources without limits or throttling, describes most of what database resource governance exists to prevent. A SQL database is a machine for accepting untrusted, caller-shaped work and refusing to let any one piece of it take the server down. Postgres expresses that refusal as a lattice of budgets: work_mem caps each sort or hash, temp_file_limit caps what a query may spill, statement_timeout caps how long it may run, max_connections caps how many callers exist at once, and maintenance_work_mem caps what index builds may hold. None of these were in the original design because someone was farsighted. Each one hardened after production incidents in which some caller-controlled quantity went unbounded.

The instructive comparison is pgvector, because it builds the same HNSW structure inside that inherited discipline. Its parameters are validated, and its build phase runs against the maintenance_work_mem budget. When a graph outgrows the budget, the build does not take the server with it. It emits a notice, "hnsw graph no longer fits into maintenance_work_mem", warns that building will take significantly more time, and continues on a slower path. The documentation's remaining advice is exactly the class rule this CVE violates: do not set the budget so high that it exhausts the memory on the server. Same algorithm, same knobs, opposite failure mode: a bounded build degrades, an unbounded one terminates. The difference is not vector-search expertise. It is twenty years of operational scar tissue encoded as defaults.

Chart of resident memory against vectors indexed during an HNSW build, comparing an unbounded build with a budgeted one. The unbounded curve climbs until it crosses the dashed host-memory line and the process is killed. The budgeted curve bends at an emerald maintenance_work_mem line, holds under it, and continues to a completed build on a slower path.

What a budget changes: the same build that would cross the host line instead flattens at the budget and finishes late.

In an agent stack, the attacker is optional

Read as a security advisory, this is a bug for internet-exposed Chroma deployments, and the immediate audience is whoever left one reachable. Read as a reliability finding, the audience is much larger, because the callers that create collections in 2026 are increasingly not people.

Vector stores sit under agent memory systems, retrieval layers, and MCP servers, and collection creation is an ordinary tool call in those stacks. Chroma's own memory product is built on exactly this write path, and the ecosystem's default wiring gives agents the ability to create and configure collections as part of doing their job. An agent does not need to be malicious to send a large ef_construction. It needs to have read a blog post. Model training data is full of advice to raise HNSW parameters when recall disappoints, and an agent tuning its own retrieval, or scaffolding a new project, will happily pick numbers a human operator would question. Unbounded parameter acceptance plus automated callers is a self-inflicted outage waiting on no adversary at all.

That reframes where the fix belongs. Authentication in front of the API closes the unauthenticated path this CVE describes, and it does nothing about the authenticated agent making the same request in good faith. The durable fix is the database one: the server enforces ceilings on what any caller may claim, whoever they are. This is the same conclusion the agent-access debate keeps arriving at from other directions, that read-only and role-scoped access do not bound the damage a permitted operation can do. A permitted collection-create with hostile sizing is the availability version of a permitted query with hostile cost. Guardrails that only check "may this caller do this operation" miss the question this incident asks, which is "may this operation be this large".

Mitigations that do not wait for a patch

As of this writing, Chroma's release notes do not yet name a version fixing the bounds check, so mitigation is deployment-side. The concrete list is short. Keep the API off the public network; an unauthenticated vector store reachable from the internet is an incident with or without this CVE. Put validation at the boundary you do control: if collection creation flows through your application or an MCP server you operate, clamp the three parameters there to the ranges your hardware has actually been tested at. Run the server under a container memory limit so that when an allocation does run away, the kernel kills one process instead of the host, and treat that kill as a signal to go find the collection whose configuration caused it. And if agents can create collections in your stack, log the index configuration they request with the same seriousness you log their writes, because memory infrastructure shared by agents is production infrastructure, and its capacity decisions deserve provenance.

The pattern to carry away is bigger than one advisory. Every young database engine re-encounters the resource-governance curriculum the older ones already paid for, and the AI infrastructure wave has produced a lot of young engines at once, running in places where the callers are tireless and the operators are stretched. When evaluating any store an agent stack depends on, the question this CVE suggests is blunt: for each number a caller can send, what bounds it, and what happens when the bound is hit? Engines with good answers degrade. Engines without them page you.

Where Datapace sits

An index sized by a caller is a capacity decision made by whoever happened to hold the API credential, and capacity decisions are precisely the kind of act a policy layer should see before the hardware does. Datapace is building toward that position for AI on databases: a context layer that carries the resolved meaning of the data alongside its operational evidence (cost, performance, usage and freshness, lineage), with a policy gate over what an agent may do and access, served over MCP. In that frame, "create a collection with ef_construction=500000" is not a schema operation to permit or deny by role; it is a resource claim to evaluate against what the workload evidence says the infrastructure can carry. If agents in your stack can already create and configure the stores they remember with, see the safe AI database access use case or book a call.

Sources

  1. NVD, CVE-2026-85664, Chroma 1.5.9 HNSW parameter bounds, September 2026.
  2. OffSeq Threat Radar, CVE-2026-85664: Allocation of Resources Without Limits or Throttling in chroma-core chroma.
  3. RedPacket Security, CVE Alert: CVE-2026-85664.
  4. pgvector, README: HNSW index options and build memory behavior, defaults m=16, ef_construction=64, hnsw.ef_search=40.
  5. chroma-core, Releases.
  6. MITRE, CWE-770: Allocation of Resources Without Limits or Throttling.

Frequently asked questions

How do I check if my Chroma deployment is exposed to CVE-2026-85664?
Confirm your server version against the advisory, then check whether the HTTP API is reachable without authentication from outside your private network. If callers you do not control can create collections, treat the deployment as exposed until a patched release is named.
What is CWE-770?
CWE-770 is Allocation of Resources Without Limits or Throttling: software that lets an input decide how much memory, CPU, or storage gets allocated without enforcing an upper bound. Unbounded uploads, unbounded connection counts, and unbounded index parameters all sit in this class.
Should HNSW parameters ever be caller-controlled?
Tuning them per collection is legitimate, since recall needs vary by workload. The operational rule is that the values should come from configuration reviewed by whoever operates the store, with a server-side ceiling, never raw from an API caller or an agent tool call.
What memory limits should I set when self-hosting a vector database?
Run the process under a container memory limit sized below the host so an out-of-memory kill takes down one service instead of the machine, alert on resident memory well before the limit, and load-test index builds at your real dimensionality before production traffic depends on them.

Keep reading

Ready to let agents touch production, safely?

Bring a use case. We will show you what agents can do on your live data, inside your guardrails.