An unresolved $ref points to a location that does not exist. The usual causes are a misspelled component name, a rename that changed only one side, or a missing file in a multi-file description.
Broken YAML
The response references #/components/schemas/User, but the document does not define User:
openapi: 3.1.0
info:
title: Users API
version: 1.0.0
paths:
/users/{userId}:
get:
operationId: getUser
parameters:
- name: userId
in: path
required: true
schema:
type: string
responses:
'200':
description: User returned
content:
application/json:
schema:
$ref: '#/components/schemas/User'
Why it fails
An internal reference uses a URI fragment with a JSON Pointer. Each segment is case-sensitive and must match the document tree exactly. In this example, the pointer asks for a User key under components.schemas, but that key is absent.
A valid reference does not require the target to appear before the reference. It only requires the target to exist after the complete document is resolved.
Corrected YAML
Define the target at the referenced location:
openapi: 3.1.0
info:
title: Users API
version: 1.0.0
paths:
/users/{userId}:
get:
operationId: getUser
parameters:
- name: userId
in: path
required: true
schema:
type: string
responses:
'200':
description: User returned
content:
application/json:
schema:
$ref: '#/components/schemas/User'
components:
schemas:
User:
type: object
properties:
id:
type: string
If the real component has a different name, update the pointer instead. For an external reference, also check the relative file path and the fragment inside that file.
OpenAPI 3.0 vs 3.1
Reference resolution still requires a real target in OpenAPI 3.0 and OpenAPI 3.1. OpenAPI 3.1 allows more useful siblings next to $ref in some contexts, but that change does not make a missing pointer valid.
Validate the fix
Use either path:
- Open the Sourced OpenAPI validator, paste the full document, and select Validate spec. It checks local JSON Pointer references.
- Run an OpenAPI linter, which can also resolve file references from the saved document:
pnpm --package=@redocly/cli@2.53.3 dlx redocly lint openapi.yaml --extends=minimal
An unresolved reference is different from a circular reference. A circular reference points to a real schema that leads back to itself. See the circular reference guide for that case.