weaviate/weaviate · error

connection to: %s failed with status: %d

Error message

connection to: %s failed with status: %d

What it means

formatError builds a descriptive error for any non-200 response from the DigitalOcean Serverless Inference API, including the status code, request-id header and API error message, and increments the module external error metric. It surfaces every HTTP-level failure the vectorizer encounters.

Source

Thrown at modules/text2vec-digitalocean/clients/digitalocean.go:230

func buildURL(ctx context.Context, baseURL string) (string, error) {
	baseURL, err := modulecomponents.ValidatedBaseURLFromHeader(ctx, "X-Digitalocean-Baseurl", baseURL)
	if err != nil {
		return "", err
	}
	return url.JoinPath(baseURL, "/v1/embeddings")
}

func formatError(statusCode int, requestID string, body *digitalOceanError) error {
	endpoint := "DigitalOcean Serverless Inference API"
	msg := fmt.Sprintf("connection to: %s failed with status: %d", endpoint, statusCode)
	if requestID != "" {
		msg = fmt.Sprintf("%s request-id: %s", msg, requestID)
	}
	if body != nil && body.Message != "" {
		msg = fmt.Sprintf("%s error: %s", msg, body.Message)
	}
	monitoring.GetMetrics().ModuleExternalError.WithLabelValues("text2vec", endpoint, msg, strconv.Itoa(statusCode)).Inc()
	return errors.New(msg)
}

// rateLimitsFromHeader parses DigitalOcean's ratelimit-* headers, which carry
// per-request totals. Tokens-per-minute is not exposed, so we set a high dummy
// limit to keep the batcher from throttling on it.
func rateLimitsFromHeader(header http.Header) *modulecomponents.RateLimits {
	limit := getHeaderInt(header, "ratelimit-limit")
	remaining := getHeaderInt(header, "ratelimit-remaining")

	var resetTime time.Time
	if resetEpoch, err := strconv.ParseInt(header.Get("ratelimit-reset"), 10, 64); err == nil && resetEpoch > 0 {
		resetTime = time.Unix(resetEpoch, 0)
	} else {
		resetTime = time.Now().Add(time.Minute)
	}

	if limit <= 0 {
		limit = dummyLimit

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Read the status code and message embedded in the error to identify the cause
  2. Fix the API key (401) or model name (404) in the module configuration
  3. Back off and retry on 429/5xx — the batcher respects rate limit headers
  4. Check the request-id against DigitalOcean support if the error persists
Defensive patterns

Strategy: retry

Validate before calling

if os.Getenv("DIGITALOCEAN_API_KEY") == "" { return errors.New("DIGITALOCEAN_API_KEY not set") }

Try / catch

_, err := vectorizer.Vectorize(ctx, texts)
var he *HTTPError
if err != nil {
  if strings.Contains(err.Error(), "status: 429") || strings.Contains(err.Error(), "status: 5") {
    // exponential backoff and retry
  }
}

Prevention

When it happens

Trigger: Any /v1/embeddings call that returns a non-OK status: 401 bad API key, 404 unknown model, 429 rate limit exceeded, 5xx server error.

Common situations: Expired or missing DIGITALOCEAN_API_KEY; typo in model name; hitting inference rate limits during batch imports; DigitalOcean region outages.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/e76684cc6e708ff3. Report an issue: GitHub.