projectdiscovery/nuclei · error
downloaded content is neither valid JSON nor YAML: %w
Error message
downloaded content is neither valid JSON nor YAML: %w
What it means
The Swagger spec URL returned HTTP 200 but the body parses as neither JSON nor YAML: the downloader tries encoding/json first, then gopkg.in/yaml.v3, and wraps the YAML parser error. Bodies like HTML pages, plain text, or binary content fail both parses; documents larger than the 10MB LimitReader cap can be truncated into invalid syntax.
Source
Thrown at pkg/input/formats/swagger/downloader.go:80
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("HTTP %d when downloading Swagger spec", resp.StatusCode)
}
bodyBytes, err := io.ReadAll(io.LimitReader(resp.Body, maxSpecSizeBytes))
if err != nil {
return "", errors.Wrap(err, "failed to read response body")
}
// Determine format and parse
var spec map[string]interface{}
var isYAML bool
// Try JSON first
if err := json.Unmarshal(bodyBytes, &spec); err != nil {
// Then try YAML
if err := yaml.Unmarshal(bodyBytes, &spec); err != nil {
return "", fmt.Errorf("downloaded content is neither valid JSON nor YAML: %w", err)
}
isYAML = true
}
// Validate it's a Swagger 2.0 spec
if swagger, exists := spec["swagger"]; exists {
if swaggerStr, ok := swagger.(string); ok && strings.HasPrefix(swaggerStr, "2.") {
// Valid Swagger 2.0 spec
} else {
return "", fmt.Errorf("not a valid Swagger 2.0 spec (found version: %v)", swagger)
}
} else {
return "", fmt.Errorf("not a Swagger spec (missing 'swagger' field)")
}
// Extract host from URL for host configuration
parsedURL, err := url.Parse(urlStr)
if err != nil {View on GitHub (pinned to 265b3a3dec)
Solutions
- curl the URL and inspect the first lines of the raw body
- If it is HTML, find the real spec link inside the page (look for spec-url / swagger config) and use that
- If truncated by size, split or trim the spec and feed it as a local file
- Ensure no proxy is injecting content (try --noproxy or a different network)
Example fix
# before (URL serves the docs UI HTML) nuclei -im swagger -u https://host/docs # after curl -s https://host/api-docs/swagger.yaml -o spec.yaml nuclei -l spec.yaml -im swagger
Defensive patterns
Strategy: validation
Validate before calling
resp, _ := http.Get(url)
body, _ := io.ReadAll(io.LimitReader(resp.Body, 10<<20))
if !json.Valid(body) {
var y any
if err := yaml.Unmarshal(body, &y); err != nil {
return fmt.Errorf("body is neither JSON nor YAML (likely HTML or truncated)")
}
} Type guard
func isJSONorYAML(body []byte) bool {
if json.Valid(body) {
return true
}
var y any
return yaml.Unmarshal(body, &y) == nil
} Try / catch
if strings.Contains(err.Error(), "neither valid JSON nor YAML") {
// inspect the raw body: usually a login/HTML page; find the real spec link
} Prevention
- Inspect the raw body once with curl before automating
- Keep specs under 10MB
- Bypass HTML-injecting proxies for spec hosts
When it happens
Trigger: Docs UI HTML returned at the spec URL; SSO/login pages answering 200; CDN error pages or CAPTCHA challenges; plain-text error messages; >10MB specs cut mid-document.
Common situations: Portals that serve the viewer app on every route; response-rewriting proxies; huge auto-generated specs exceeding the size cap.
Related errors
- downloaded content is not valid JSON: %w
- object can be a key:value or a string
- URL does not appear to be a Swagger spec (supported: %v)
- HTTP %d when downloading Swagger spec
- failed to download %s spec from url %s: %w
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/32c19cea4d21df29.
Report an issue: GitHub.