apache/shenyu · error · IllegalArgumentException

Invalid Swagger JSON format:

Error message

Invalid Swagger JSON format: 

What it means

validateSwaggerContent() catches all exceptions during JSON parsing/version detection and re-throws IllegalArgumentException('Invalid Swagger JSON format: ' + message). It fires when the fetched content is not parseable JSON at all (JsonSyntaxException / parse error), not merely a wrong version. The original parse message is appended for diagnosis.

Solutions

  1. Inspect the appended message in 'Invalid Swagger JSON format: ...' to see the exact parse failure.
  2. curl the URL and confirm the body is pure JSON (login/error HTML is the most common culprit).
  3. Fix auth so the raw JSON document is served without redirect or HTML wrapping.
  4. Validate the JSON with a linter/JSON parser before importing.
Defensive patterns

Strategy: validation

Validate before calling

String body = fetch(swaggerUrl);
if (body == null || body.isBlank()) throw new IllegalArgumentException("empty response from swagger URL");
try { JsonParser.parseString(body); } catch (JsonSyntaxException e) {
    throw new IllegalArgumentException("URL did not return JSON (got HTML/error page?): " + e.getMessage());
}

Try / catch

try {
    service.importSwagger(request);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Invalid Swagger JSON format")) {
        // log the raw fetched body to inspect what was actually returned
    }
    throw e;
}

Prevention

When it happens

Trigger: The swaggerUrl returns HTML (login page, error page), an empty body, or truncated/malformed JSON — the initial docRoot parse inside the try block throws and is converted to IllegalArgumentException.

Common situations: Endpoint redirects to an SSO login page returning HTML; proxy returns a gzip/compressed body that is not decoded; response body truncated by a size limit; content served as JSON5 or with comments.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/f23fdb8ac03d476a. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImpl.java:300



    private void validateSwaggerContent(final String swaggerJson) {
        try {
            JsonObject docRoot = GsonUtils.getInstance().fromJson(swaggerJson, JsonObject.class);
            
            // Detect version
            boolean isV2 = docRoot.has("swagger") && docRoot.get("swagger").getAsString().startsWith("2.");
            boolean isV3 = docRoot.has("openapi") && docRoot.get("openapi").getAsString().startsWith("3.");
            
            if (!isV2 && !isV3) {
                throw new IllegalArgumentException("Unsupported Swagger version, only Swagger 2.0 and OpenAPI 3.0 formats are supported");
            }
            
            LOG.info("Detected Swagger version: {}", isV2 ? "2.0" : "3.0");
            
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid Swagger JSON format: " + e.getMessage());
        }
    }
    
    private UpstreamInstance createVirtualInstance(final SwaggerImportRequest request) {
        UpstreamInstance instance = new UpstreamInstance();
        instance.setContextPath(request.getProjectName());
        
        // Try to parse IP and port from URL
        try {
            URL url = new URL(request.getSwaggerUrl());
            instance.setIp(url.getHost());
            instance.setPort(url.getPort() == -1 ? (url.getProtocol().equals("https") ? 443 : 80) : url.getPort());
        } catch (Exception e) {
            instance.setIp("unknown");
            instance.setPort(80);
        }
        
        return instance;

View on GitHub (pinned to 567142e072)