cocoindex-io/cocoindex · error · ValueError
Unsupported Qdrant distance metric: {distance}
Error message
Unsupported Qdrant distance metric: {distance} What it means
The Qdrant connector maps user-friendly distance strings to qdrant_client Distance enums. Only "cosine", "dot"/"dotproduct", and "euclid"/"euclidean"/"l2" are accepted; any other string in QdrantVectorDef.distance raises this ValueError at collection creation time.
Source
Thrown at python/cocoindex/connectors/qdrant/_target.py:666
def _collection_exists(client: QdrantClient, collection_name: str) -> bool:
if hasattr(client, "collection_exists"):
return bool(client.collection_exists(collection_name))
try:
client.get_collection(collection_name)
return True
except Exception:
return False
def _distance_from_spec(distance: str) -> qdrant_models.Distance:
distance_key = distance.lower()
if distance_key in ("cosine",):
return qdrant_models.Distance.COSINE
if distance_key in ("dot", "dotproduct"):
return qdrant_models.Distance.DOT
if distance_key in ("euclid", "euclidean", "l2"):
return qdrant_models.Distance.EUCLID
raise ValueError(f"Unsupported Qdrant distance metric: {distance}")
def _multivector_comparator(
comparator: str,
) -> qdrant_models.MultiVectorComparator:
"""Convert multivector comparator string to Qdrant enum."""
if comparator.lower() == "max_sim":
return qdrant_models.MultiVectorComparator.MAX_SIM
raise ValueError(f"Unsupported multivector comparator: {comparator}")
def _sparse_modifier_from_spec(
modifier: Literal["idf"] | None,
) -> qdrant_models.Modifier | None:
if modifier is None:
return None
if modifier == "idf":
return qdrant_models.Modifier.IDFView on GitHub (pinned to e84aa99b32)
Solutions
- Change distance to one of: "cosine", "dot", "dotproduct", "euclid", "euclidean", "l2".
- Lowercase the value before passing (matching is case-sensitive and exact).
- If you need a metric Qdrant does not support via this helper (e.g. manhattan), pick the closest supported one or implement it client-side.
Example fix
// before QdrantVectorDef(schema=vec, distance="Cosine") // after QdrantVectorDef(schema=vec, distance="cosine")
Defensive patterns
Strategy: validation
Validate before calling
_ALLOWED = {"cosine", "dot", "dotproduct", "euclid", "euclidean", "l2"}
assert distance in _ALLOWED, f"distance must be one of {sorted(_ALLOWED)}, got {distance!r}" Type guard
distance in {"cosine", "dot", "dotproduct", "euclid", "euclidean", "l2"} Try / catch
try:
schema = await CollectionSchema.create(vectors=QdrantVectorDef(schema=vec, distance=dist))
except ValueError as e:
log.error("bad distance %r", dist)
raise Prevention
- Keep distance strings lowercase in config files and validate at load time.
- Centralize the metric string in one constant instead of inlining across call sites.
- Map external metric names (e.g. Milvus "ip") to Qdrant names in one adapter.
When it happens
Trigger: Setting `distance=` on QdrantVectorDef to an unsupported string, e.g. "Cosine" (capitalized), "manhattan", "hamming", or an empty string; the value flows through _vector_params_from_def -> _distance_from_spec when the collection is created.
Common situations: Copying distance names from another vector DB (e.g. "ip" from Milvus, "inner_product"); YAML config with capitalized or hyphenated values like "Cosine" or "cosine-dist"; typo such as "cosin".
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Unsupported multivector comparator: {comparator}
- Unsupported Qdrant sparse vector modifier: {modifier}
- Invalid metric name: {metric}
- qdrant-client is required to use the Qdrant connector. Pleas
- Invalid vector definition: {vector_def}
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/c9601ef10acf3e26.
Report an issue: GitHub.