Skip to content

/codes/postgresql/postgresql-sqlstate-error-codes

PostgreSQL SQLSTATE error codes: 23505, 23503, 42P01, 40001 and more

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated 2026-10-20
tool
PostgreSQL
versions
PostgreSQL 12 – 18
os
any

Every PostgreSQL error carries a five-character SQLSTATE code. The first two characters are the class (23 integrity constraint violation, 42 syntax or access rule violation, 40 transaction rollback). Handle errors by code, not by message: messages can be translated (lc_messages) and reworded between versions.

Codes applications handle

SQLSTATENameTypical causeUsual handling
23505unique_violationduplicate primary key or unique valuereturn "already exists", or upsert
23503foreign_key_violationreferenced row missing, or still referenced on deletevalidation error
23502not_null_violationNULL in a NOT NULL columnvalidation error
23514check_violationCHECK constraint failedvalidation error
22P02invalid_text_representation'abc'::int, bad UUID textvalidate input first
22012division_by_zerox / 0fix the query, NULLIF(y, 0)
42P01undefined_tabletable missing or not on search_pathdeployment or migration bug
42703undefined_columnmisspelled or missing columndeployment or migration bug
40001serialization_failureconflict under SERIALIZABLE or REPEATABLE READretry the whole transaction
40P01deadlock_detectedtwo transactions wait for each otherretry; lock rows in a consistent order
55P03lock_not_availableNOWAIT or lock_timeout reachedretry later
57014query_canceledstatement_timeout or a cancel requestoptimise, or raise the timeout
53300too_many_connectionsmax_connections reacheduse a connection pool

Real codes from PostgreSQL 18

bash
npm init -y >/dev/null
npm install --silent --no-audit --no-fund @electric-sql/pglite@0.5.10 >/dev/null 2>&1
cat > q.mjs <<'EOF'
import { PGlite } from "@electric-sql/pglite";
const db = new PGlite();
await db.exec(`create table users (id int primary key, email text not null unique check (email like '%@%'));
               create table orders (id int primary key, user_id int references users(id));
               insert into users values (1, 'a@example.com');`);
for (const sql of [
  `insert into users values (1, 'b@example.com')`,
  `insert into orders values (1, 99)`,
  `insert into users values (2, null)`,
  `insert into users values (3, 'no-at-sign')`,
  `select 'abc'::int`,
  `select 1 / 0`,
  `select * from missing_table`,
  `select nme from users`,
]) {
  try { await db.query(sql); } catch (e) { console.log(e.code.padEnd(6), e.message); }
}
EOF
node q.mjs

Output

23505  duplicate key value violates unique constraint "users_pkey"
23503  insert or update on table "orders" violates foreign key constraint "orders_user_id_fkey"
23502  null value in column "email" of relation "users" violates not-null constraint
23514  new row for relation "users" violates check constraint "users_email_check"
22P02  invalid input syntax for type integer: "abc"
22012  division by zero
42P01  relation "missing_table" does not exist
42703  column "nme" does not exist

In drivers the code is a property of the error: err.code in node-postgres, e.sqlstate in psycopg 3, getSQLState() in JDBC.

Sources