Current Behavior
While performing concurrent ingestion using the Qdrant Python client (HTTP mode, httpx==0.27.2), I consistently encounter the following error:
httpx.RemoteProtocolError: Server disconnected without sending a response
This happens even with very small batch sizes (15 points) and a semaphore-limited maximum of 5 concurrent ingestion threads.
Steps to Reproduce
- Using Qdrant in Docker (
image:v1.13.4)
- Ingesting ~15 points per batch using
qdrant_client.upsert(...)
Ingestion function is attached below:
` # Prepare points for embeddings based on mode
for i, doc in enumerate(documents):
# Create point structure with common fields
point = PointStruct(
id=str(uuid.uuid4()),
vector={
dense_vector_name: dense_embeddings[i],
sparse_vector_name: sparse_embeddings[i],
},
payload={
"page_content": doc.page_content,
"metadata": doc.metadata
}
)
points.append(point)
logger.debug(f"Size of points to be stored in collection {collection_name} is {len(points)}")
# Upload all embeddings at once
if semaphore:
with semaphore:
self.qdrant_client.upsert(
collection_name=collection_name,
points=points,
wait=False
)
else:
self.qdrant_client.upsert(
collection_name=collection_name,
points=points,
wait=False
)
logger.info(f"Successfully added {len(documents)} splits to the collection {collection_name} in the qdrant vector database.")`
-
Both dense and sparse vectors are used per point
-
Upsert is called inside a function wrapped in a Semaphore(5) (tried 3 also) to limit concurrency. I have also tried it without semaphore but issue persists.
-
wait=Falseor wait=True both tested — issue persists
-
HTTP client is httpx==0.27.2
Expected Behavior
Qdrant should either:
Respond with an error (e.g., 503 Service Unavailable, memory limit exceeded), or
Continue to handle small batch ingestion under moderate concurrency without dropping connections unexpectedly
Possible Solution
Context (Environment)
Qdrant version: latest (Docker image)
Qdrant client version: qdrant-client==1.8.0
httpx version: 0.27.2
Python: 3.11
Platform: Ubuntu 22.04, running in AWS EC2
Running inside Docker: Yes
Number of parallel ingestion threads: 5 (semaphore-limited)
Batch size: 15 points
Each point includes: dense (768d) + sparse embeddings + metadata
Detailed Description
The ingestion runs successfully for a number of batches, then randomly fails with:
ERROR - Traceback (most recent call last):
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpx/_transports/default.py", line 72, in map_httpcore_exceptions
yield
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpx/_transports/default.py", line 236, in handle_request
resp = self._pool.handle_request(req)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpcore/_sync/connection_pool.py", line 256, in handle_request
raise exc from None
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpcore/_sync/connection_pool.py", line 236, in handle_request
response = connection.handle_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpcore/_sync/connection.py", line 103, in handle_request
return self._connection.handle_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpcore/_sync/http11.py", line 136, in handle_request
raise exc
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpcore/_sync/http11.py", line 106, in handle_request
) = self._receive_response_headers(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpcore/_sync/http11.py", line 177, in _receive_response_headers
event = self._receive_event(timeout=timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpcore/_sync/http11.py", line 231, in _receive_event
raise RemoteProtocolError(msg)
httpcore.RemoteProtocolError: Server disconnected without sending a response.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/qdrant_client/http/api_client.py", line 116, in send_inner
response = self._client.send(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpx/_client.py", line 926, in send
response = self._send_handling_auth(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpx/_client.py", line 954, in _send_handling_auth
response = self._send_handling_redirects(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpx/_client.py", line 991, in _send_handling_redirects
response = self._send_single_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpx/_client.py", line 1027, in _send_single_request
response = transport.handle_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpx/_transports/default.py", line 235, in handle_request
with map_httpcore_exceptions():
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/contextlib.py", line 158, in __exit__
self.gen.throw(typ, value, traceback)
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/httpx/_transports/default.py", line 89, in map_httpcore_exceptions
raise mapped_exc(message) from exc
httpx.RemoteProtocolError: Server disconnected without sending a response.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/ubuntu/actransit-cdr/corporate-data-repository/app/vectorization/vector_store/qdrant_vector_store.py", line 165, in create_vector_store
self.qdrant_client.upsert(
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/qdrant_client/qdrant_client.py", line 1567, in upsert
return self._client.upsert(
^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/qdrant_client/qdrant_remote.py", line 1908, in upsert
http_result = self.openapi_client.points_api.upsert_points(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/qdrant_client/http/api/points_api.py", line 987, in upsert_points
return self._build_for_upsert_points(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/qdrant_client/http/api/points_api.py", line 512, in _build_for_upsert_points
return self.api_client.request(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/qdrant_client/http/api_client.py", line 89, in request
return self.send(request, type_)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/qdrant_client/http/api_client.py", line 106, in send
response = self.middleware(request, self.send_inner)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/qdrant_client/http/api_client.py", line 215, in __call__
return call_next(request)
^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/miniconda3/envs/new_cdr/lib/python3.11/site-packages/qdrant_client/http/api_client.py", line 118, in send_inner
raise ResponseHandlingException(e)
qdrant_client.http.exceptions.ResponseHandlingException: Server disconnected without sending a response.
Possible Implementation
Current Behavior
While performing concurrent ingestion using the Qdrant Python client (HTTP mode, httpx==0.27.2), I consistently encounter the following error:
httpx.RemoteProtocolError: Server disconnected without sending a responseThis happens even with very small batch sizes (15 points) and a semaphore-limited maximum of 5 concurrent ingestion threads.
Steps to Reproduce
image:v1.13.4)qdrant_client.upsert(...)Ingestion function is attached below:
Both dense and sparse vectors are used per point
Upsert is called inside a function wrapped in a
Semaphore(5)(tried 3 also) to limit concurrency. I have also tried it withoutsemaphorebut issue persists.wait=Falseorwait=Trueboth tested — issue persistsHTTP client is
httpx==0.27.2Expected Behavior
Qdrant should either:
Respond with an error (e.g., 503 Service Unavailable, memory limit exceeded), or
Continue to handle small batch ingestion under moderate concurrency without dropping connections unexpectedly
Possible Solution
Context (Environment)
Qdrant version: latest (Docker image)
Qdrant client version:
qdrant-client==1.8.0httpx version: 0.27.2Python: 3.11Platform: Ubuntu 22.04, running in AWS EC2
Running inside Docker: Yes
Number of parallel ingestion threads: 5 (semaphore-limited)
Batch size: 15 points
Each point includes: dense (768d) + sparse embeddings + metadata
Detailed Description
The ingestion runs successfully for a number of batches, then randomly fails with:
Possible Implementation