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
- Log/inspect the actual status code in the wrapped error
- For 403: change egress IP or verify the Chrome-mimicking headers still match current Cloudflare expectations
- For 400/404: compare the request body and sploitusAPIURL against the current Sploitus API contract and update the searcher
- 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
- Keep browser-mimicking headers in sync with current Cloudflare expectations
- Verify the API endpoint/contract after any Sploitus change
- Maintain alternate engines (e.g. other exploit searchers) for automatic failover
- Log full status + a body snippet for fast triage of 403/400 responses
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
- Sploitus API rate limit exceeded (HTTP %d), please try again
- failed to decode Sploitus response: %w
- unexpected status code: %d
- unexpected status code: %d
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/3bf80afefe554913.
Report an issue: GitHub.