Skip to content

Upsert with Cloud Inference vectors hangs indefinitely (HTTP/2 issue with undici) #131

@andreyobsidiam

Description

@andreyobsidiam

Problem

Using `@qdrant/js-client-rest` to upsert points with Cloud Inference vectors (using `vector: { text, model }` syntax) causes the request to hang indefinitely — never resolving or rejecting — when running inside a Docker container.

Reproduction

```js
const { QdrantClient } = require('@qdrant/js-client-rest');

const client = new QdrantClient({
url: 'https://xyz.cloud.qdrant.io',
apiKey: process.env.QDRANT_API_KEY,
checkCompatibility: false,
});

await client.upsert('my-collection', {
wait: true,
points: [
{
id: 1,
vector: { text: 'hello world', model: 'openai' },
payload: {},
},
],
});
// Hangs forever — no timeout, no error, no response
```

Environment:

  • Node.js v20.20.2
  • @qdrant/js-client-rest 1.17.0
  • undici 6.24.1
  • Running inside Docker (docker-compose)

Workaround

Using Node.js native `https.request` (HTTP/1.1) instead of the undici-based client works perfectly — returns 200 in ~222ms inside Docker.

```js
// This works inside Docker:
const https = require('https');
// ... manual HTTPS request with http1Only ...
```

Also confirmed: `curl --http2` from the host machine also hangs when targeting the inference endpoint, confirming the issue manifests at the HTTP/2 protocol level.

Root Cause Analysis

The `@qdrant/js-client-rest` package uses undici as its HTTP transport. While `allowH2` defaults to `false` in undici v6, HTTPS connections perform ALPN negotiation. If the server advertises h2, some versions/configurations may still negotiate HTTP/2, which then hangs on certain Qdrant Cloud inference endpoints inside Docker networking.

Suggested Fix

Add `allowH2: false` explicitly to the undici `Agent` options in `packages/js-client-rest/src/dispatcher.ts` to guarantee HTTP/1.1 and avoid any ALPN-based HTTP/2 upgrade:

```ts
// packages/js-client-rest/src/dispatcher.ts
new Agent({
bodyTimeout: 0,
headersTimeout: 0,
connections,
keepAliveTimeout: 10_000,
allowH2: false, // ← explicitly disable HTTP/2
})
```

This is a one-line, zero-risk change that makes the HTTP/1.1 guarantee explicit rather than relying on the undici default.

Version Info

  • `@qdrant/js-client-rest`: 1.17.0
  • undici: 6.24.1
  • Node.js: v20.20.2
  • Docker: docker-compose
  • OS: macOS (host), Debian-based (container)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions