fix(health): forward api-key to Qdrant /readyz so Cloud probes work

The readiness handler called the configured `qdrant_url/readyz` with a
bare httpx.AsyncClient — no headers. That works against a self-hosted
Qdrant (where /readyz is anonymous), but Qdrant Cloud's auth gateway
returns 403 for any unauthenticated request, including /readyz, /livez
and /healthz. Result: every probe against a Cloud cluster fell into
the "status 403" branch, the handler returned 503, and the Pod never
went Ready — even when the configured `AsyncQdrantClient` itself was
authenticating fine for actual collection traffic.

Forward `settings.qdrant_api_key` as the `api-key` header (mirroring
what `vector/qdrant_client.py:540` already does for the real client).
When the key is unset (self-hosted, anonymous case) we send no header,
so existing self-hosted deployments are unchanged.

Verified end-to-end against Qdrant Cloud:
- Without header: GET /readyz -> 403 {"error":"forbidden"}
- With api-key:  same request shape returns 200 (matches what
  AsyncQdrantClient.wait() relies on internally).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-05-10 20:15:05 +02:00
co-authored by Claude Opus 4.7
parent 635dfd7a33
commit 9cb0b33ec1
+13 -1
View File
@@ -1960,9 +1960,21 @@ def get_app(transport: str = "streamable-http", enabled_apps: list[str] | None =
if vector_sync_enabled and qdrant_url:
start_time = time.time()
# Self-hosted Qdrant exposes /readyz unauthenticated, but
# Qdrant Cloud's auth gateway returns 403 for any
# unauthenticated request — so we have to forward the same
# api-key the configured AsyncQdrantClient uses (see
# vector/qdrant_client.py). Without this header, every
# readiness probe against a Cloud cluster returns 503,
# blocking the Pod from reaching Ready.
qdrant_headers = (
{"api-key": settings.qdrant_api_key} if settings.qdrant_api_key else {}
)
try:
async with httpx.AsyncClient(timeout=2.0) as client:
response = await client.get(f"{qdrant_url}/readyz")
response = await client.get(
f"{qdrant_url}/readyz", headers=qdrant_headers
)
duration = time.time() - start_time
if response.status_code == 200:
checks["qdrant"] = "ok"