OpenAPITools/openapi-generator · error · ResponseStatusException

The OpenAPI specification supplied was not valid

Error message

The OpenAPI specification supplied was not valid

What it means

Thrown when the swagger-parser call returned a result whose getOpenAPI() is null (Generator.java:94-111), meaning the input could not be turned into an OpenAPI model at all. For inline specs, readContents yields a null model when the payload is not recognizable YAML/JSON (e.g. an HTML error page, an empty document, or garbage). For openAPIUrl, readLocation yields null when the URL cannot be fetched or its content is unparseable — critically, the URL is fetched server-side, from the generator host's network, not the client's.

Source

Thrown at modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/service/Generator.java:110

                    List<AuthorizationValue> authorizationValues = new ArrayList<>();
                    authorizationValues.add(opts.getAuthorizationValue());
                    openapi = new OpenAPIParser().readLocation(opts.getOpenAPIUrl(), authorizationValues, parseOptions).getOpenAPI();
                } else {
                    openapi = new OpenAPIParser().readLocation(opts.getOpenAPIUrl(), null, parseOptions).getOpenAPI();
                }
            } else {
                throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "No OpenAPI specification was supplied");
            }
        } else if (opts.getAuthorizationValue() != null) {
            List<AuthorizationValue> authorizationValues = new ArrayList<>();
            authorizationValues.add(opts.getAuthorizationValue());
            openapi = new OpenAPIParser().readContents(node.toString(), authorizationValues, parseOptions).getOpenAPI();

        } else {
            openapi = new OpenAPIParser().readContents(node.toString(), null, parseOptions).getOpenAPI();
        }
        if (openapi == null) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "The OpenAPI specification supplied was not valid");
        }


        // do not use opts.getOptions().get("outputFolder") as the input can contain ../../
        // to access other folders in the server
        String destPath = language + "-" + type.getTypeName();

        ClientOptInput clientOptInput = new ClientOptInput();
        String outputFolder = getTmpFolder().getAbsolutePath() + File.separator + destPath;
        String outputFilename = outputFolder + "-bundle.zip";

        clientOptInput.openAPI(openapi);

        CodegenConfig codegenConfig;
        try {
            codegenConfig = CodegenConfigLoader.forName(language);
        } catch (RuntimeException e) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Unsupported target " + language + " supplied");

View on GitHub (pinned to fcec517be3)

Solutions

  1. Inline the spec in the body ("spec": ...) instead of "openAPIUrl" so no server-side fetch is needed
  2. If using openAPIUrl, make sure the URL is reachable from the generator server (public or same network), and test with curl FROM the server
  3. For auth-protected specs, supply "authorizationValue": {"value": "...", "type": "header", "keyName": "Authorization"}
  4. Pre-validate the document locally with swagger-parser or a validator before submitting

Example fix

# before
{"openAPIUrl": "http://localhost:8080/openapi.json"}   # server cannot reach YOUR localhost -> 400 not valid

# after
# fetch it yourself, then inline it
{"spec": $(curl -s https://internal-host/openapi.json)}
Defensive patterns

Strategy: validation

Validate before calling

// parse locally first with the same parser the server uses
SwaggerParseResult r = new OpenAPIParser().readContents(specJson, null, new ParseOptions());
if (r.getOpenAPI() == null) throw new IllegalArgumentException("spec unparseable: " + r.getMessages());
// for URLs: prefer inlining — the server fetches from ITS network, not yours

Type guard

boolean isFetchableSpecUrl(String url) {
    try {
        HttpURLConnection c = (HttpURLConnection) new URI(url).toURL().openConnection();
        c.setConnectTimeout(3000);
        return c.getResponseCode() == 200
            && (c.getContentType() == null || c.getContentType().contains("json")
                || c.getContentType().contains("yaml"));
    } catch (Exception e) { return false; }
}

Try / catch

catch (HttpClientErrorException.BadRequest e) {
    if (e.getResponseBodyAsString().contains("not valid")) {
        // null model = unparseable/unfetchable source; inline the spec instead of the URL
        input.setOpenAPIUrl(null);
        input.setSpec(fetchAndParseSpecLocally());
    }
}

Prevention

When it happens

Trigger: openAPIUrl pointing at localhost/127.0.0.1 or an intranet host unreachable from the generator server; URL returning HTML (login page, 404 handler) instead of the spec; inline spec that is malformed YAML/JSON or empty; URL with a typo or wrong scheme; private repo URL without an authorizationValue.

Common situations: Developers testing against a spec served by their own machine ('works when I open the URL in my browser'); specs behind auth where authorizationValue was omitted; gateways that answer 200 with an HTML error body; copy-pasted URLs with trailing garbage or smart quotes.

Related errors


AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22). Data as JSON: /api/errors/649b67bff86f8999. Report an issue: GitHub.