SQLSTATE 42P01 ERROR Class 42: Syntax Error or Access Rule Violation

undefined_table relation “…” does not exist — 42P01

PostgreSQL error "relation "…" does not exist" (SQLSTATE 42P01): what it means, common causes, and how to fix it.

PG 12, 13, 14, 15, 16, 17, 18 Official docs
Last reviewed May 2025 Grounded in source

Diagnostic Queries

Symptoms

A query failed because the table, view, materialized view, or sequence you named cannot be found in any schema on the current search_path. In PostgreSQL a “relation” means any of those table-like objects, so this one message covers a missing table or view or sequence.

  • The statement aborts immediately; the client receives SQLSTATE 42P01.
  • The log shows a caret (^) under the unresolved name.
  • Often appears right after a deploy, a schema change, or connecting to the wrong database.

What the server log shows

ERROR:  relation "orders" does not exist
LINE 1: SELECT * FROM orders;
                      ^
STATEMENT:  SELECT * FROM orders;

Why PostgreSQL raises this — what the manual says

Section 5.10.3 The Schema Search Path:

“If there is no match in the search path, an error is reported, even if matching table names exist in other schemas in the database.”

The parser resolves an unqualified name by walking the schemas in search_path (default "$user", public) in order. If no schema on that path contains the relation, name resolution fails with 42P01. Unquoted identifiers are folded to lower case first, so SELECT * FROM Orders looks for orders, not Orders.

Common causes

  • A typo or wrong case in the name (unquoted identifiers fold to lower case).
  • The object lives in a schema that is not on search_path.
  • The table was dropped, renamed, or never created.
  • You are connected to the wrong database.
  • A migration ran against a different schema/search_path than the query.

How to fix it

  1. List the object and its schema: \dt *.* in psql, or query pg_catalog.pg_tables.
  2. Schema-qualify the name (analytics.events) or fix the path: SHOW search_path; then SET search_path TO analytics, public;.
  3. Confirm the database: SELECT current_database();.
  4. If the name has mixed case, quote it exactly: SELECT * FROM "Orders";.

Diagnostic query

-- Find every schema that contains a relation by this name
SELECT n.nspname AS schema, c.relname, c.relkind
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = 'orders';

relkind tells you what it is: r=table, v=view, m=materialized view, S=sequence, p=partitioned table.

Related & next steps

Reference: PostgreSQL 18 Section 5.9 “Schemas”.

Was this helpful?