{"record":{"id":"6fab7cc256bb83ed","repo":"MemPalace/mempalace","slug":"qdrant-returned-invalid-json","errorCode":null,"errorMessage":"Qdrant returned invalid JSON","messagePattern":"Qdrant returned invalid JSON","errorType":"exception","errorClass":"BackendError","httpStatus":null,"severity":"error","filePath":"mempalace/backends/qdrant.py","lineNumber":406,"sourceCode":"            headers[\"api-key\"] = self._config.api_key\n        if body is not None:\n            data = json.dumps(body, ensure_ascii=False).encode(\"utf-8\")\n        req = urlrequest.Request(url, data=data, method=method, headers=headers)\n        try:\n            with urlrequest.urlopen(req, timeout=self._config.timeout) as resp:\n                raw = resp.read()\n        except urlerror.HTTPError as exc:\n            raw = exc.read()\n            detail = raw.decode(\"utf-8\", errors=\"replace\") if raw else str(exc)\n            raise _QdrantHTTPError(exc.code, detail) from exc\n        except urlerror.URLError as exc:\n            raise BackendError(f\"Qdrant request failed: {exc.reason}\") from exc\n        if not raw:\n            return {}\n        try:\n            return json.loads(raw.decode(\"utf-8\"))\n        except json.JSONDecodeError as exc:\n            raise BackendError(\"Qdrant returned invalid JSON\") from exc\n\n    def collection_exists(self, collection: str) -> bool:\n        try:\n            self.request(\"GET\", f\"/collections/{urlparse.quote(collection, safe='')}\")\n        except _QdrantHTTPError as exc:\n            if exc.status == 404:\n                return False\n            raise\n        return True\n\n    def get_collection_info(self, collection: str) -> dict:\n        return self.request(\"GET\", f\"/collections/{urlparse.quote(collection, safe='')}\")\n\n    def create_collection(self, collection: str, dimension: int) -> None:\n        self.request(\n            \"PUT\",\n            f\"/collections/{urlparse.quote(collection, safe='')}\",\n            body={\"vectors\": {\"size\": int(dimension), \"distance\": \"Cosine\"}},","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/qdrant.py#L388-L424","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from mempalace.backends.base import BackendError\ntry:\n    info = client.request(\"GET\", \"/collections\")\nexcept BackendError as e:\n    if \"invalid JSON\" in str(e):\n        # proxy or wrong endpoint answered; inspect raw response with curl","preventionTips":["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"],"tags":["network","json","qdrant","proxy"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}