Overview
An OpenAPI (formerly Swagger) specification is the contract describing what an API does, what data it expects, and what it returns. Documentation tools like Swagger UI, testing tools like Postman, and code generators like openapi-generator all read this single document and assume it's structurally correct. A spec that's even slightly malformed, a missing required field, a broken reference, a duplicate identifier, can break every tool downstream, often with confusing error messages pointing at the symptom rather than the actual mistake.
Validating an OpenAPI spec means checking two levels: is the YAML or JSON well-formed, and does the document conform to the OpenAPI schema's structural rules. This guide walks through both, then the common errors that slip past a quick glance, and finally verification against real API behavior, the one thing no automated validator can do for you. Run your spec through the OpenAPI Validator as you work through each step.
What You Need
- The OpenAPI or Swagger spec file, in YAML or JSON format
- Knowledge of which spec version your document declares (2.0, 3.0.x, or 3.1.x)
- Access to your actual running API, or at least its documented sample requests and responses, for the final behavioral check
- The OpenAPI Validator to check schema compliance automatically
Step 1: Understand OpenAPI Spec Versions
Three versions are in active use today, and they aren't interchangeable. OpenAPI 2.0, originally called Swagger, uses a swagger: "2.0" declaration and a definitions section for reusable schemas. OpenAPI 3.0 replaced this with openapi: "3.0.x" and moved reusable schemas to components/schemas, alongside other structural changes to how request bodies and security schemes get declared. OpenAPI 3.1, the most recent, aligned the spec fully with JSON Schema 2020-12 and added native support for webhooks.
Before validating anything, confirm which version your document declares in its first few lines. A validator checking 3.1 rules against a 2.0 document, or the reverse, produces a wall of irrelevant errors that have nothing to do with the actual problems in your spec.
Step 2: Check Structural Validity (YAML/JSON Syntax)
Before any semantic validation, confirm the document itself is well-formed YAML or JSON. This is a separate, more basic check than OpenAPI schema compliance. It matters because a single syntax error, one bad indentation level in YAML, one missing comma in JSON, can cascade into dozens of confusing downstream errors that obscure the actual root cause.
YAML is particularly prone to this because indentation carries meaning. A block indented one space too far or too few silently changes which parent key it belongs to, with no obvious error since the document still parses as valid YAML, just with a different structure than intended. Run a plain YAML or JSON linter first, before OpenAPI-specific validation, so any errors you see afterward are genuinely about OpenAPI compliance and not basic syntax.
Step 3: Validate Against the OpenAPI Schema
With syntax confirmed, check the document against the OpenAPI specification's own schema. At minimum, every valid document needs:
- A version declaration (
openapi: "3.0.3"orswagger: "2.0") matching the actual structure used elsewhere in the document - An
infoobject containing at leasttitleandversionfor the API itself (not to be confused with the OpenAPI spec version) - A
pathsobject describing at least one operation (OpenAPI 3.1 relaxes this if webhooks are defined instead)
Beyond these top-level requirements, the schema also constrains the shape of every nested object: parameters, request bodies, responses, security schemes, each with its own required fields and allowed types. Use the OpenAPI Validator to check full compliance in one pass rather than cross-referencing the spec field by field.
Step 4: Check for Common Semantic Errors
Some errors pass basic schema validation but still cause real problems downstream:
- Duplicate operationIds. Every
operationIdmust be unique across the entire document, not just within a single path. Duplicates commonly appear when a spec is assembled from multiple files, or when an operation gets copy-pasted as a starting point for a new endpoint and the ID never gets updated. Code generators rely on operationId to name generated functions, so duplicates cause silent overwrites or outright generation failures. - Broken $ref pointers. A
$reflike#/components/schemas/Userhas to point to a schema that actually exists at that exact path. Renaming a schema in one place without updating every reference to it is the most common cause, and the failure often surfaces far from the actual typo. - Required parameters with no usable example. A parameter marked
required: truewith no example or default value forces every consumer of the spec to guess what a valid value looks like. It's technically valid OpenAPI, just a poor practice that creates friction for anyone building against the API. - Inconsistent response status codes. A path documenting a
201response while the matching response schema undercomponentswas written for a200means the spec and the implementation drifted out of sync somewhere along the way.
Step 5: Test Against Real API Behavior
A spec that passes every structural and semantic check can still be wrong about what the real API actually does. Validators check internal consistency and schema compliance. They have no way of knowing whether the live API actually returns the fields, types, and status codes the spec claims it does.
Cross-check a handful of real requests and responses against the spec by hand. Call a documented endpoint and compare the actual JSON response shape against what the spec's response schema describes. Pay attention to fields the spec marks required but the API sometimes omits, and to enum values that don't cover every value the live API can return. Contract-testing tools that replay recorded traffic against the spec catch some of this drift automatically, once you have a validated baseline spec to test against.
Common Mistakes to Avoid
Confusing Swagger 2.0 and OpenAPI 3.x syntax. These versions use genuinely different structures: definitions versus components/schemas, different ways of declaring request bodies and security schemes. Copy-pasting a snippet from a 2.0 spec into a 3.x document, or the reverse, produces validation failures that look confusing if you don't recognize the syntax as belonging to the wrong version.
Leaving placeholder or stale example data in production specs. Example values that don't match what the real API returns mislead anyone using the spec to understand or test the API, even though the spec stays technically valid. This is a correctness problem the validator can't catch, since examples are documentation, not enforced constraints.
Not validating after every edit. Treating validation as a pre-release checkpoint rather than a continuous habit lets small errors pile up. A typo introduced in a minor edit three weeks ago is much harder to trace than one caught the moment it happened. Running validation as part of a pre-commit hook or CI step catches problems while they're still cheap to fix.
Formula & Methodology
OpenAPI's request and response bodies are described using JSON Schema syntax nested inside the broader OpenAPI document, which means OpenAPI validation really runs two layers stacked together. The outer layer checks the document against the OpenAPI meta-schema: are info, paths, and other top-level fields present and correctly shaped. The inner layer checks each embedded schema definition under components/schemas against JSON Schema's own validation rules: types, required properties, enum constraints, and so on. OpenAPI 3.1 uses JSON Schema 2020-12 directly. OpenAPI 3.0 and Swagger 2.0 use earlier, more restricted subsets with a few OpenAPI-specific keywords (like nullable) that don't exist in standalone JSON Schema.
This layered structure explains why a single broken $ref inside a deeply nested schema can produce an error message that seems to point at an unrelated top-level field. The validator is reporting the outer-layer symptom of an inner-layer problem.
The practical tooling chain matters too. OpenAPI specs typically feed directly into Swagger UI or Redoc for documentation rendering, Postman for import-and-test workflows, and openapi-generator or similar tools for generating client SDKs and server stubs. An invalid spec doesn't just break a documentation page. It breaks every tool in this chain at once, which is why validating the spec itself, before it reaches any of these tools, is the highest-leverage place to catch errors.