chroma-core/chroma · error · Error

Failed to generate embeddings

Error message

Failed to generate embeddings: ${response.statusText}

What it means

HuggingFaceEmbeddingServerFunction.generate() POSTs { inputs: texts } to the configured url (a HuggingFace inference / TEI endpoint) with the headers built at construction. If the response status is not 2xx it throws carrying only response.statusText (e.g. "Unauthorized", "Not Found") — the response body, which usually contains the actual reason, is discarded, so you must reproduce the request to diagnose the root cause.

Solutions

  1. Reproduce the exact call to see status and body: curl -X POST "$URL" -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{"inputs":["ping"]}'
  2. Confirm the env var named by api_key_env_var is exported in the process making the call (node -e "console.log(!!process.env.HF_TOKEN)")
  3. Verify the URL scheme/host/route against the HuggingFace or TEI endpoint documentation
  4. For 5xx/503 responses, confirm the server is up (logs/health endpoint) before retrying with backoff

Example fix

// before (library code): only statusText is visible
throw new Error(`Failed to generate embeddings: ${response.statusText}`);

// after (library-level): keep status and body
const body = await response.text();
throw new Error(`Failed to generate embeddings: ${response.status} ${response.statusText} ${body.slice(0, 200)}`);
Defensive patterns

Strategy: try-catch

Validate before calling

async function pingEmbedServer(url: string, headers: Record<string, string>): Promise<void> {
  const res = await fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify({ inputs: ["ping"] }),
    signal: AbortSignal.timeout(5_000),
  });
  if (!res.ok) throw new Error(`embedding server unhealthy: ${res.status} ${res.statusText}`);
}
// run during startup probes, before relying on generate()

Try / catch

try {
  embeddings = await ef.generate(texts);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Failed to generate embeddings")) {
    // statusText-only failure: log it, check auth env var and URL; retry only on transient 5xx, never blind-retry 4xx
  }
  throw e;
}

Prevention

When it happens

Trigger: Wrong endpoint URL or missing route (404); Authorization header missing/invalid because the env var named by api_key_env_var is unset or empty (401); server overloaded or behind a proxy returning 502/503; request body exceeding the server limit (413).

Common situations: Pointing at the HuggingFace model page URL instead of the inference endpoint URL; HF token set in the local shell but not in the container; TEI container not running when the client starts; corporate gateways stripping Authorization headers.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/fa7975b979894e7c. Report an issue: GitHub.

Appendix: source

Thrown at clients/js/packages/chromadb-core/src/embeddings/HuggingFaceEmbeddingServerFunction.ts:49

      apiKey = api_key;
    }
    this.url = url;
    if (apiKey) {
      this.headers = {
        Authorization: `Bearer ${apiKey}`,
      };
    }
  }

  public async generate(texts: string[]) {
    const response = await fetch(this.url, {
      method: "POST",
      headers: this.headers,
      body: JSON.stringify({ inputs: texts }),
    });

    if (!response.ok) {
      throw new Error(`Failed to generate embeddings: ${response.statusText}`);
    }

    const data = await response.json();
    return data;
  }

  buildFromConfig(config: StoredConfig): HuggingFaceEmbeddingServerFunction {
    return new HuggingFaceEmbeddingServerFunction({
      url: config.url,
      api_key_env_var: config.api_key_env_var,
    });
  }

  getConfig(): StoredConfig {
    return {
      url: this.url,
      api_key_env_var: this.api_key_env_var,
    };

View on GitHub (pinned to aecdd12c8a)