ERROR 42703: Column Does Not Exist in Postgres
Error Message
ERROR: column "emial" does not exist
LINE 1: SELECT emial FROM users;
^
SQLSTATE: 42703Description
PostgreSQL raises error 42703 when a query references a column that the database cannot find in the target table or expression. The full SQLSTATE code is 42703 (undefined_column). This is one of the most common PostgreSQL errors â closely related to 42P01 (undefined table) â and usually traces back to a spelling mistake, a missing alias, or a schema mismatch.
Causes
- Typo in the column name.
SELECT emial FROM usersfails because the column is actuallyemail. - Missing table alias or wrong alias. In a multi-table query, referencing
SELECT name FROM orders JOIN customers c ON ...fails ifnameexists incustomersbut notordersand no alias is specified. - Case sensitivity. If a column was created with double quotes (
"Status"), you must always reference it as"Status". Without quotes, PostgreSQL folds identifiers to lowercase, soSELECT StatusbecomesSELECT statuswhich won't match"Status". - Column dropped or renamed. A migration renamed
user_nametousernamebut application code still references the old name. - Wrong table in a JOIN. The column exists in a different table than the one being referenced.
- Subquery or CTE column not exposed. A subquery selects
idbut the outer query referencesuser_idfrom that subquery. - Schema mismatch after migration. The application expects a column that a migration hasn't created yet, or that was rolled back.
Solutions
-
Check the actual column names in the table:
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'users' ORDER BY ordinal_position; -
Use a table alias to disambiguate columns in JOINs:
-- Bad: ambiguous or wrong table SELECT name FROM orders JOIN customers ON orders.customer_id = customers.id; -- Good: qualify with alias SELECT c.name FROM orders o JOIN customers c ON o.customer_id = c.id; -
Handle case-sensitive column names:
-- If created with double quotes SELECT "Status" FROM orders; -- Check actual casing SELECT column_name FROM information_schema.columns WHERE table_name = 'orders' AND column_name ILIKE '%status%'; -
Verify the column in psql:
\d users -
Check subquery or CTE column names:
-- Bad: outer query references a column the CTE doesn't expose WITH active AS (SELECT id FROM users WHERE active = true) SELECT user_id FROM active; -- Good: match the column name WITH active AS (SELECT id FROM users WHERE active = true) SELECT id FROM active; -
Run pending migrations:
If the column should have been added by a migration, verify it was applied:
# Check migration status flyway info # Or check the change history in Bytebase
Common scenarios
In ORMs and application code: ORMs map model fields to column names. If you rename a field in your model but forget to generate a migration, or if the migration hasn't been applied, PostgreSQL will report 42703 at runtime. Check \d tablename against your model definition.
In GROUP BY and ORDER BY: PostgreSQL doesn't allow referencing column aliases in WHERE or HAVING (though ORDER BY is fine). SELECT email AS e FROM users WHERE e LIKE '%@%' fails with 42703 because aliases aren't visible in WHERE.
-- Bad
SELECT email AS e FROM users WHERE e LIKE '%@%';
-- Good
SELECT email AS e FROM users WHERE email LIKE '%@%';After ALTER TABLE: If a column was renamed with ALTER TABLE users RENAME COLUMN user_name TO username, any view, function, or application query still using the old name will fail with 42703. Search your codebase for the old column name.
Bytebase's SQL Review can catch references to non-existent columns during change review, before they reach production. See also ERROR 42P01: Relation Does Not Exist for the related table-not-found error.