vxcontrol/pentagi · error

Sploitus API returned HTTP %d

Error message

Sploitus API returned HTTP %d

What it means

Any Sploitus response status other than 200, 499, 422, and not 429/>=500 produces this Fatal error (no retry). 429 and 5xx are Retryable; everything else (403 Cloudflare block, 404, 400) is treated as permanent for this engine.

Source

Thrown at backend/pkg/tools/searchers/sploitus.go:166

	req.Header.Set("sec-fetch-dest", "empty")
	req.Header.Set("sec-fetch-mode", "cors")
	req.Header.Set("sec-fetch-site", "same-origin")
	req.Header.Set("DNT", "1")

	resp, err := client.Do(req)
	if err != nil {
		return "", Retryable(fmt.Errorf("request to Sploitus failed: %w", err), 0)
	}
	defer resp.Body.Close()

	// Sploitus API returns 499 (and sometimes 422) when its rate limit is temporarily
	// exceeded — a transient condition that may clear on retry.
	if resp.StatusCode == 499 || resp.StatusCode == 422 {
		return "", Retryable(fmt.Errorf("Sploitus API rate limit exceeded (HTTP %d), please try again later", resp.StatusCode), 0)
	}

	if resp.StatusCode != http.StatusOK {
		err := fmt.Errorf("Sploitus API returned HTTP %d", resp.StatusCode)
		if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode >= 500 {
			return "", Retryable(err, 0)
		}
		return "", Fatal(err)
	}

	var apiResp sploitusResponse
	if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
		return "", Fatal(fmt.Errorf("failed to decode Sploitus response: %w", err))
	}

	return formatSploitusResults(query, exploitType, limit, apiResp), nil
}

// IsAvailable returns true if the Sploitus tool is enabled and configured
func (s *sploitus) IsAvailable() bool {
	return s.enabled()
}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Log/inspect the actual status code in the wrapped error
  2. For 403: change egress IP or verify the Chrome-mimicking headers still match current Cloudflare expectations
  3. For 400/404: compare the request body and sploitusAPIURL against the current Sploitus API contract and update the searcher
  4. Rely on web_search fallback engines until Sploitus is reachable again
Defensive patterns

Strategy: fallback

Try / catch

if resp.StatusCode != http.StatusOK {
    // Non-retryable statuses (403 Cloudflare, 400) — switch engine
    return "", Fatal(fmt.Errorf("Sploitus API returned HTTP %d", resp.StatusCode))
}

Prevention

When it happens

Trigger: Handle() gets a non-200 status: typically 403 when Cloudflare blocks the mimicked browser request, or 400 from an API change; 429/5xx instead return the Retryable branch.

Common situations: Cloudflare hard-blocks the datacenter/container IP (403), Sploitus changes its API path/contract, or the request payload becomes invalid after a refactor.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/3bf80afefe554913. Report an issue: GitHub.