{"record":{"id":"32c19cea4d21df29","repo":"projectdiscovery/nuclei","slug":"downloaded-content-is-neither-valid-json-nor-yaml","errorCode":null,"errorMessage":"downloaded content is neither valid JSON nor YAML: %w","messagePattern":"downloaded content is neither valid JSON nor YAML: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/input/formats/swagger/downloader.go","lineNumber":80,"sourceCode":"\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"HTTP %d when downloading Swagger spec\", resp.StatusCode)\n\t}\n\n\tbodyBytes, err := io.ReadAll(io.LimitReader(resp.Body, maxSpecSizeBytes))\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to read response body\")\n\t}\n\n\t// Determine format and parse\n\tvar spec map[string]interface{}\n\tvar isYAML bool\n\n\t// Try JSON first\n\tif err := json.Unmarshal(bodyBytes, &spec); err != nil {\n\t\t// Then try YAML\n\t\tif err := yaml.Unmarshal(bodyBytes, &spec); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"downloaded content is neither valid JSON nor YAML: %w\", err)\n\t\t}\n\t\tisYAML = true\n\t}\n\n\t// Validate it's a Swagger 2.0 spec\n\tif swagger, exists := spec[\"swagger\"]; exists {\n\t\tif swaggerStr, ok := swagger.(string); ok && strings.HasPrefix(swaggerStr, \"2.\") {\n\t\t\t// Valid Swagger 2.0 spec\n\t\t} else {\n\t\t\treturn \"\", fmt.Errorf(\"not a valid Swagger 2.0 spec (found version: %v)\", swagger)\n\t\t}\n\t} else {\n\t\treturn \"\", fmt.Errorf(\"not a Swagger spec (missing 'swagger' field)\")\n\t}\n\n\t// Extract host from URL for host configuration\n\tparsedURL, err := url.Parse(urlStr)\n\tif err != nil {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/input/formats/swagger/downloader.go#L62-L98","documentation":"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.","triggerScenarios":"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.","commonSituations":"Portals that serve the viewer app on every route; response-rewriting proxies; huge auto-generated specs exceeding the size cap.","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)"],"exampleFix":"# before (URL serves the docs UI HTML)\nnuclei -im swagger -u https://host/docs\n\n# after\ncurl -s https://host/api-docs/swagger.yaml -o spec.yaml\nnuclei -l spec.yaml -im swagger","handlingStrategy":"validation","validationCode":"resp, _ := http.Get(url)\nbody, _ := io.ReadAll(io.LimitReader(resp.Body, 10<<20))\nif !json.Valid(body) {\n    var y any\n    if err := yaml.Unmarshal(body, &y); err != nil {\n        return fmt.Errorf(\"body is neither JSON nor YAML (likely HTML or truncated)\")\n    }\n}","typeGuard":"func isJSONorYAML(body []byte) bool {\n    if json.Valid(body) {\n        return true\n    }\n    var y any\n    return yaml.Unmarshal(body, &y) == nil\n}","tryCatchPattern":"if strings.Contains(err.Error(), \"neither valid JSON nor YAML\") {\n    // inspect the raw body: usually a login/HTML page; find the real spec link\n}","preventionTips":["Inspect the raw body once with curl before automating","Keep specs under 10MB","Bypass HTML-injecting proxies for spec hosts"],"tags":["swagger","parsing","yaml","json","download"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}