projectdiscovery/nuclei · error
HTTP %d when downloading OpenAPI spec
Error message
HTTP %d when downloading OpenAPI spec
What it means
OpenAPIDownloader.Download fetched the URL successfully but got a non-200 HTTP status. The response status is embedded in the message (e.g. HTTP 401, 404, 503). The request goes through the configured retryablehttp client (or a 30s-timeout fallback), so this is purely a server-side response code failure after transport succeeded.
Source
Thrown at pkg/input/formats/openapi/downloader.go:55
var client *http.Client
if httpClient != nil {
client = httpClient.HTTPClient
} else {
// Fallback to simple client if no httpClient provided
client = &http.Client{Timeout: 30 * time.Second}
}
resp, err := client.Get(urlStr)
if err != nil {
return "", errors.Wrap(err, "failed to download OpenAPI spec")
}
defer func() {
_ = resp.Body.Close()
}()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("HTTP %d when downloading OpenAPI spec", resp.StatusCode)
}
bodyBytes, err := io.ReadAll(io.LimitReader(resp.Body, maxSpecSizeBytes))
if err != nil {
return "", errors.Wrap(err, "failed to read response body")
}
// Validate it's a valid JSON and has OpenAPI structure
var spec map[string]interface{}
if err := json.Unmarshal(bodyBytes, &spec); err != nil {
return "", fmt.Errorf("downloaded content is not valid JSON: %w", err)
}
// Check if it's an OpenAPI 3.0 spec
if openapi, exists := spec["openapi"]; exists {
if openapiStr, ok := openapi.(string); ok && strings.HasPrefix(openapiStr, "3.") {
// Valid OpenAPI 3.0 spec
} else {View on GitHub (pinned to 265b3a3dec)
Solutions
- Verify the URL with `curl -i <url>` and confirm it returns 200 from the same network/proxy context
- If the spec needs auth headers, download it yourself (curl -H 'Authorization: ...' -o spec.json) and run `nuclei -l spec.json`
- Check proxy environment variables (HTTP_PROXY/HTTPS_PROXY) and bypass rules in nuclei config
- For transient 5xx/429, retry after a delay or from a different network
Example fix
# before (spec endpoint requires auth -> HTTP 401) nuclei -im openapi -u https://internal/api/openapi.json # after curl -sH "Authorization: Bearer $TOKEN" https://internal/api/openapi.json -o spec.json nuclei -l spec.json
Defensive patterns
Strategy: retry
Validate before calling
resp, err := http.Head(url) // or retryablehttp
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("preflight: spec URL returned %d; fix URL/auth before running nuclei", resp.StatusCode)
} Try / catch
var path string
var err error
for attempt := 0; attempt < 3; attempt++ {
path, err = downloader.Download(url, tmp, client)
if err == nil {
break
}
if strings.Contains(err.Error(), "HTTP 5") || strings.Contains(err.Error(), "HTTP 429") {
time.Sleep(time.Duration(attempt+1) * 2 * time.Second)
continue
}
return err // 4xx: fail fast, retrying will not help
} Prevention
- curl -i the spec URL from the same network before starting a scan
- Use locally downloaded specs for auth-gated endpoints (nuclei -l spec.json)
- Keep proxy exclusions current for internal spec hosts
When it happens
Trigger: 401/403 from an auth-gated spec endpoint; 404 from a wrong or moved spec path; 302→login page when a redirect target does not return 200; 429/5xx from rate limiting or transient outages; corporate proxy returning 407.
Common situations: Internal API portals that require session cookies or bearer tokens (the downloader sends none); stale spec URLs after API restructuring; CI environments behind proxies that intercept the request; rate-limited public APIs.
Related errors
- HTTP %d when downloading Swagger spec
- downloaded content is not valid JSON: %w
- failed to download %s spec from url %s: %w
- URL does not appear to be an OpenAPI JSON spec
- not a valid OpenAPI 3.0 spec (found version: %v)
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/c83e71eb8e73c593.
Report an issue: GitHub.