MemPalace/mempalace · error · BackendError
Qdrant returned invalid JSON
Error message
Qdrant returned invalid JSON
What it means
Raised by QdrantClient.request() when the Qdrant server answered the HTTP request with a 200-level response whose body is not valid JSON. The REST client expects JSON on every endpoint; a body that fails json.loads raises BackendError.
Source
Thrown at mempalace/backends/qdrant.py:406
headers["api-key"] = self._config.api_key
if body is not None:
data = json.dumps(body, ensure_ascii=False).encode("utf-8")
req = urlrequest.Request(url, data=data, method=method, headers=headers)
try:
with urlrequest.urlopen(req, timeout=self._config.timeout) as resp:
raw = resp.read()
except urlerror.HTTPError as exc:
raw = exc.read()
detail = raw.decode("utf-8", errors="replace") if raw else str(exc)
raise _QdrantHTTPError(exc.code, detail) from exc
except urlerror.URLError as exc:
raise BackendError(f"Qdrant request failed: {exc.reason}") from exc
if not raw:
return {}
try:
return json.loads(raw.decode("utf-8"))
except json.JSONDecodeError as exc:
raise BackendError("Qdrant returned invalid JSON") from exc
def collection_exists(self, collection: str) -> bool:
try:
self.request("GET", f"/collections/{urlparse.quote(collection, safe='')}")
except _QdrantHTTPError as exc:
if exc.status == 404:
return False
raise
return True
def get_collection_info(self, collection: str) -> dict:
return self.request("GET", f"/collections/{urlparse.quote(collection, safe='')}")
def create_collection(self, collection: str, dimension: int) -> None:
self.request(
"PUT",
f"/collections/{urlparse.quote(collection, safe='')}",
body={"vectors": {"size": int(dimension), "distance": "Cosine"}},View on GitHub (pinned to 06cb6987f0)
Solutions
- curl the exact URL the client uses and inspect the raw body: curl -s http://host:6333/collections | head -c 500
- If a proxy returns HTML, fix proxy routing/auth so /collections/* reaches Qdrant directly
- Verify the URL points at a real Qdrant instance (GET / should return Qdrant version JSON)
- Retry once — truncation from transient network faults is usually not reproducible
- Check proxy buffering/caching settings (proxy_buffering off, no cache for API paths)
Defensive patterns
Strategy: try-catch
Try / catch
from mempalace.backends.base import BackendError
try:
info = client.request("GET", "/collections")
except BackendError as e:
if "invalid JSON" in str(e):
# proxy or wrong endpoint answered; inspect raw response with curl Prevention
- Smoke-test the endpoint with curl when first configuring the backend
- Don't put an auth/HTML-returning proxy in front of the Qdrant REST API
- If behind nginx, disable caching/buffering for the Qdrant paths
When it happens
Trigger: A proxy (nginx, corporate MITM, service mesh sidecar) returns an HTML error/login page with 200 status; the URL actually points at a non-Qdrant service; a truncated response due to a connection cut after headers; a server version returning plain-text on some endpoint.
Common situations: Reverse proxy in front of Qdrant intercepting requests and returning HTML auth pages; pointing the config at the wrong service that answers 200 with HTML; flaky network truncating the body; proxy_cache serving corrupted content.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Malformed response from {url}: {e}
- Qdrant request failed: {exc.reason}
- operator {op!r} not supported by chroma backend
- operator {key!r} not supported by chroma backend
- operator {key!r} not supported by qdrant
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/6fab7cc256bb83ed.
Report an issue: GitHub.