OpenAPI validation errors block documentation generation, break code generators, and prevent CI pipelines from passing. The error messages are often cryptic — a single misplaced property can cascade into dozens of downstream failures.
This guide covers the 10 most common validation errors across OpenAPI 3.0 and 3.1 specs, ordered by frequency. Each error includes the exact error message you will see, why it happens, and a before/after YAML fix.
1. Broken $ref Path
Error: Can't resolve $ref: #/components/schemas/user
The most common OpenAPI error. A $ref points to a schema that does not exist — usually because of a case mismatch or typo.
# The $ref says "user" but the schema is "User"
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/user' # lowercase
components:
schemas:
User: # uppercase
type: objectrequestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User' # matches exactly
components:
schemas:
User:
type: objectFix: $ref values are case-sensitive. Search your spec for every $ref and verify the target exists with the exact same casing.
2. Missing responses Object
Error: Operation must have at least one response defined
Every operation (get, post, etc.) requires a responses object. This is easy to forget on draft endpoints.
paths:
/health:
get:
summary: Health check
# No responses definedpaths:
/health:
get:
summary: Health check
responses:
'200':
description: Service is healthy3. Invalid type Value
Error: Schema type must be one of: string, number, integer, boolean, array, object
OpenAPI 3.0 only allows six types. Common mistakes: using float (use number with format: float), date (use string with format: date), or null (use nullable: true in 3.0, or type: ['string', 'null'] in 3.1).
# These are NOT valid OpenAPI types
properties:
price:
type: float # not a valid type
birthday:
type: date # not a valid type
deleted_at:
type: null # not valid in 3.0properties:
price:
type: number
format: float
birthday:
type: string
format: date
deleted_at:
type: string
format: date-time
nullable: true # OpenAPI 3.0
# For 3.1: type: ['string', 'null']4. Example/Default Type Mismatch
Error: Example value "100" is not valid for schema type integer
YAML treats unquoted numbers as integers and quoted values as strings. If your schema says type: integer but your example is "100"(a string), validation fails.
properties:
port:
type: integer
example: "8080" # string, not integer
enabled:
type: boolean
example: "true" # string, not booleanproperties:
port:
type: integer
example: 8080 # unquoted = integer
enabled:
type: boolean
example: true # unquoted = boolean5. Duplicate operationId
Error: operationId "getUser" is already used by another operation
Every operationId must be unique across the entire spec. This commonly happens when copy-pasting endpoint definitions.
Fix: Use a consistent naming convention like verb + Resource: listUsers, getUser, createUser, updateUser, deleteUser.
6. Missing or Invalid info Object
Error: Info object must have a title and version
The info object at the root of every spec requires title and version. Both must be strings. A common mistake: using a number for version.
openapi: 3.0.3
info:
title: My API
version: 1.0 # number, not stringopenapi: 3.0.3
info:
title: My API
version: "1.0" # stringValidate and publish in one step
Specway validates your spec on import, highlights errors inline, and generates documentation from the valid portions while you fix issues.
Import Your Spec7. Path Parameter Not Declared
Error: Path parameter "id" must be defined in the parameters section
If your path contains {id}, there must be a matching parameter definition with in: path and required: true.
paths:
/users/{id}: # {id} in path
get:
summary: Get user
responses:
'200':
description: OK
# No parameters defined for {id}paths:
/users/{id}:
get:
summary: Get user
parameters:
- name: id
in: path
required: true # path params MUST be required
schema:
type: string
responses:
'200':
description: OK8. Required Field Not in Properties
Error: Required property "email" is not defined in properties
Every item in the required array must match a key in properties. Typos in either location cause this error.
schemas:
User:
type: object
required:
- email # listed as required
properties:
email_address: # but the property is named differently
type: stringschemas:
User:
type: object
required:
- email_address # matches the property name
properties:
email_address:
type: string9. Invalid HTTP Status Code
Error: Response status code must be a string "200", not integer 200
In OpenAPI, HTTP status codes under responses must be strings (quoted). YAML interprets unquoted 200 as an integer.
responses:
200: # YAML sees this as integer
description: OK
404:
description: Not foundresponses:
'200': # quoted string
description: OK
'404':
description: Not found10. Array Without items
Error: Schema of type array must have an items property
Every type: array schema requires an items definition. Without it, tools cannot generate types or validate responses.
properties:
tags:
type: array
# Missing items definitionproperties:
tags:
type: array
items:
type: stringValidation Tools
Run validation before every commit. Here are the main options:
# Spectral (most popular, customizable rules)
npx @stoplight/spectral-cli lint openapi.yaml
# Redocly CLI
npx @redocly/cli lint openapi.yaml
# swagger-cli (basic validation)
npx swagger-cli validate openapi.yaml
# Online: paste your spec at editor.swagger.ioAdd linting to CI so invalid specs never reach production:
# .github/workflows/lint-spec.yml
name: Lint OpenAPI
on: [pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx @stoplight/spectral-cli lint openapi.yamlFrequently Asked Questions
What is the best tool to validate an OpenAPI spec?
Spectral by Stoplight is the most widely used. Run it with npx @stoplight/spectral-cli lint openapi.yaml or integrate into CI. For browser-based validation, editor.swagger.io and Redocly both work.
What is the difference between OpenAPI 3.0 and 3.1 validation?
OpenAPI 3.1 aligns with JSON Schema 2020-12. The biggest change: nullable fields use type: ['string', 'null'] instead of nullable: true. It also supports $id, $anchor, and if/then/else in schemas. Most errors come from mixing 3.0 and 3.1 syntax in the same spec.
Why does my valid YAML fail OpenAPI validation?
Valid YAML is not necessarily valid OpenAPI. The YAML syntax may parse correctly, but the structure can still violate OpenAPI rules — missing responses, invalid $ref paths, wrong property nesting. Always use an OpenAPI-specific validator, not just a YAML parser.