weaviate/weaviate · error
connection to VoyageAI API failed with status %d
Error message
connection to VoyageAI API failed with status %d
What it means
The VoyageAI rerank API returned a non-2xx HTTP status but the response body either failed to parse as an error object or had an empty `message` field, so Weaviate reports only the status code. It indicates an upstream rejection whose details were not exposed in the expected format.
Source
Thrown at modules/reranker-voyageai/clients/ranker.go:148
return nil, errors.Wrap(err, "send POST request")
}
defer res.Body.Close()
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
return nil, errors.Wrap(err, "read response body")
}
if res.StatusCode != 200 {
var apiError voyageAiApiError
err = json.Unmarshal(bodyBytes, &apiError)
if err != nil {
return nil, errors.Wrap(err, "unmarshal error from response body")
}
if apiError.Message != "" {
return nil, errors.Errorf("connection to VoyageAI API failed with status %d: %s", res.StatusCode, apiError.Message)
}
return nil, errors.Errorf("connection to VoyageAI API failed with status %d", res.StatusCode)
}
var rankResponse RankResponse
if err := json.Unmarshal(bodyBytes, &rankResponse); err != nil {
return nil, fmt.Errorf("failed to parse reranker response (status %d): %w", res.StatusCode, err)
}
return c.toDocumentScores(documents, rankResponse.Data), nil
}
func (c *client) chunkDocuments(documents []string, chunkSize int) [][]string {
var requests [][]string
for i := 0; i < len(documents); i += chunkSize {
end := i + chunkSize
if end > len(documents) {
end = len(documents)
}
View on GitHub (pinned to 75aa4b6d11)
Solutions
- Check VoyageAI service status for incidents causing bare 5xx responses
- Inspect any proxy/load balancer between Weaviate and the internet that may strip or replace response bodies
- Validate the configured API key and model with a direct curl call to see the real status
- Retry with backoff for 429/5xx; fix credentials for 401/403
Defensive patterns
Strategy: retry
Validate before calling
func preflightVoyageai(ctx context.Context, apiKey string) error {
if apiKey == "" { return errors.New("VOYAGEAI_APIKEY is not set") }
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.voyageai.com/v1/models", nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
res, err := http.DefaultClient.Do(req)
if err != nil { return err }
defer res.Body.Close()
io.Copy(io.Discard, res.Body)
if res.StatusCode >= 400 { return fmt.Errorf("voyageai preflight failed: %d", res.StatusCode) }
return nil
} Try / catch
results, err := voyageClient.Rank(ctx, query, docs)
if err != nil {
if isRetryable(err) { // 429/5xx per the status text
return withBackoff(func() error { _, err = voyageClient.Rank(ctx, query, docs); return err })
}
return fmt.Errorf("rerank failed without upstream detail: %w", err)
} Prevention
- Set proxy env vars correctly so upstream error bodies aren't replaced by gateway HTML
- Monitor VoyageAI status for bare 5xx incidents
- Retry 429/5xx with exponential backoff
- Log the full response when this occurs to capture missing-body conditions
When it happens
Trigger: performRank received e.g. 401/429/500 from api.voyageai.com with an empty body, an HTML error page (proxy/gateway), or a JSON body lacking the `message` field.
Common situations: Corporate proxies or API gateways returning HTML error pages; VoyageAI returning empty-bodied 5xx during incidents; rate-limit responses without a JSON message.
Related errors
- connection to VoyageAI API failed with status %d: %s
- failed to parse reranker error response (status %d): %w
- connection to NVIDIA API failed with status: %d
- failed to parse reranker response (status %d): %w
- no model provided
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/cd2d2386781da766.
Report an issue: GitHub.