Encountering the ERROR: relation "tablename" does not exist is one of the most frequent challenges for developers and database administrators working with PostgreSQL. This specific error occurs when the database server is unable to locate the table, view, sequence, or index you are attempting to reference in your SQL command.
It typically stems from a misunderstanding of the schema search path, case sensitivity in identifiers, or the restricted permissions of the current user. This guide provides four reliable methods to diagnose and resolve this error immediately.
Table of Contents
Key Takeaways for Resolving Relation Errors
- Search Path → PostgreSQL identifies objects by following a
search_path, which is a prioritized list of schemas. If your table is in a schema not listed here, the system will report that it does not exist. - Case Sensitivity → Unquoted identifiers are automatically folded to lower case by the PostgreSQL parser. If a table was created with double quotes (e.g.,
"MyTable"), it must be queried using quotes, or the system will look formytableand fail. - Fully Qualified Names → You can bypass search path issues entirely by using a qualified name in the format
schema.table. - Schema USAGE → A user cannot “look up” or access any object without the
USAGEprivilege on the parent schema, even if they own the table. - Database Isolation → Tables are strictly isolated within their specific database; a query in
db_acannot see a table residing indb_b.
Method 1: Adjusting the Schema search_path
PostgreSQL uses the search_path to determine which schema to check when a table is referenced by its name alone (an unqualified name). By default, this path is set to "$user", public.
To resolve issues where a table exists in a custom schema, you can check your current path using SHOW search_path;. If your schema (e.g., myschema) is missing, you can add it to your current session using the command SET search_path TO myschema, public;. This makes all objects in that schema visible for the remainder of your connection. For a deeper dive, see What is search path in PostgreSQL and How to Configure it.
Method 2: Using Fully Qualified Names
If you do not want to modify your session settings, the most reliable method to fix the error is to use a fully qualified name. This involves prefixing the table name with its schema and a period, such as schema_name.table_name.
For example, instead of running SELECT * FROM orders;, you would use SELECT * FROM sales.orders;. This explicitly tells PostgreSQL exactly where to find the relation, ignoring the search_path entirely. This is often the best practice for scripts and applications to prevent ambiguity.
Method 3: Handling Case-Sensitive Identifiers
PostgreSQL handles identifiers (names for tables and columns) differently than the standard SQL “upper case folding”. In PostgreSQL, unquoted names are folded to lower case.
If you created a table using double quotes, such as CREATE TABLE "Users" (...);, PostgreSQL stores the name exactly as written. If you then attempt to query it as SELECT * FROM Users;, the parser reads it as users and returns a “relation does not exist” error. To fix this, you must always use double quotes in your query: SELECT * FROM "Users";.
Step-by-Step Process to Troubleshoot the Error
- Verify Your Connection Ensure you are connected to the correct database. Use
SELECT current_database();to confirm your context. - Locate the Table Use the psql meta-command
\dtto list all available tables you have permission to see. If the table doesn’t appear, it may be in a different database or you lack permissions. Learn more in Finding your tables in PostgreSQL. - Check Schema USAGE Confirm that your role has been granted
USAGEon the schema containing the table. RunGRANT USAGE ON SCHEMA schema_name TO user_name;if necessary. - Confirm the search_path If the table is visible via
\dtbut not your query, runSHOW search_path;and update it to include the target schema. - Audit the Table Name Check for typos or case-sensitivity issues by querying the system catalog:
SELECT relname FROM pg_class WHERE relname ILIKE '%your_table%';.
Common Relation Error Fixes
| Root Cause | Diagnostic Command | Solution |
|---|---|---|
| Schema not in path | SHOW search_path; | SET search_path TO schema, public; |
| Case sensitivity | \dt (check for caps) | Use double quotes "TableName" |
| Wrong database | SELECT current_database(); | Connect to the correct DB using \c |
| Missing permissions | \dn+ (check usage) | GRANT USAGE ON SCHEMA name TO user; |
| Typo in name | \dt | Correct the spelling in your SQL |
FAQs
Why does \dt show my table but SELECT says it doesn’t exist? The \dt command displays all tables visible to you across all schemas. However, a standard SELECT only searches the schemas listed in your search_path. Use a fully qualified name to confirm this.
Does the error “relation does not exist” apply to sequences? Yes. In PostgreSQL, tables, sequences, and views are all considered relations and share the same namespace within a schema.
See also: Mastering the Linux Command Line — Your Complete Free Training Guide
How do I avoid this error when running automated scripts? When dropping tables, use the IF EXISTS clause (e.g., DROP TABLE IF EXISTS my_table;) to prevent the script from failing if the relation is already missing.




