projectdiscovery/nuclei · error

not a valid Swagger 2.0 spec (found version: %v)

Error message

not a valid Swagger 2.0 spec (found version: %v)

What it means

The downloaded document parsed as JSON/YAML and has a top-level `swagger` field, but its value does not start with "2." (the value is printed in the message). SwaggerDownloader only supports Swagger 2.0 documents; an OpenAPI 3.x value ("3.0.1"), a non-string type, or a bogus version is rejected.

Source

Thrown at pkg/input/formats/swagger/downloader.go:90

	// 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 {
		return "", errors.Wrap(err, "failed to parse URL")
	}

	host := parsedURL.Host
	scheme := parsedURL.Scheme
	if scheme == "" {
		scheme = "https"
	}

	// Add host if missing

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. If the document is OpenAPI 3.x, use `-im openapi` instead (JSON, .json URL)
  2. If the version string is malformed (e.g. "2"), fix it to "2.0" in the spec
  3. Convert 3.x down to 2.0 only if you must stay in swagger mode
  4. Read the 'found version' in the message to see what the server actually served

Example fix

# before (3.x doc in swagger mode)
nuclei -im swagger -u https://host/openapi.json

# after
nuclei -im openapi -u https://host/openapi.json
Defensive patterns

Strategy: validation

Validate before calling

var spec map[string]any
json.Unmarshal(body, &spec) // or yaml
if v, ok := spec["swagger"].(string); !ok || !strings.HasPrefix(v, "2.") {
    if ov, _ := spec["openapi"].(string); strings.HasPrefix(ov, "3.") {
        return fmt.Errorf("use -im openapi for this document")
    }
}

Type guard

func isSwagger2(spec map[string]any) bool {
    v, ok := spec["swagger"].(string)
    return ok && strings.HasPrefix(v, "2.")
}

Try / catch

if strings.Contains(err.Error(), "not a valid Swagger 2.0 spec") {
    // switch input mode to openapi for 3.x documents, or fix a malformed version string
}

Prevention

When it happens

Trigger: Feeding an OpenAPI 3 spec (which usually uses `openapi:` but some tools duplicate it as swagger: "3...") to `-im swagger`; generators emitting swagger: "2" without minor version; mislabeled internal specs.

Common situations: Guessing the input mode when a company has mixed v2/v3 specs; conversion tools that leave stale swagger keys; hand-edited version fields.

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/06ea171c7fec6b72. Report an issue: GitHub.