Incident brief
Syntax error
PostgreSQL's parser rejected the statement because it didn't match valid SQL grammar — here, an unquoted reserved key word used as a table name.
In 10 seconds
- What
- Syntax error
- What triggers it
- Try to CREATE TABLE using a reserved SQL key word as the name, without quoting it.
- The fix
- Quote the identifier with double quotes so PostgreSQL treats it as a name, not a key word.
- Proof
- Reproduced on PostgreSQL 16.14 → Creating a table named order, unquoted, was rejected with SQLSTATE 42601. No table was created.
The fix
What to do right now
The immediate, application-level response to this error.
- Quote the identifier with double quotes so PostgreSQL treats it as a name, not a key word.
- Prefer a name that isn't a reserved word at all, so you don't need to quote it everywhere it's used.
- Quoting only fixes reserved-word collisions — it does not fix an unrelated missing-keyword syntax error, see the premium test.
CREATE TABLE "order" (id int);Diagnose
See it live on the server
Run these against the affected instance to confirm the diagnosis before you act.
Standard triage — not specific to this error
These are canonical PostgreSQL system-catalog queries, shown as SQL to run. No sample output is attached because this is general triage, not a captured lab transcript.This SQLSTATE does not have an error-specific live snapshot yet. These are the canonical system-catalog queries you run against the affected server to see the problem in real time — standard triage, not a reproduced transcript.
What is running right now
Active backends, how long each has been running, and what it is waiting on.
SELECT pid,
state,
wait_event_type,
wait_event,
now() - query_start AS running_for,
left(query, 80) AS query
FROM pg_stat_activity
WHERE state <> 'idle'
AND pid <> pg_backend_pid()
ORDER BY running_for DESC NULLS LAST;Who is blocking whom
Turn raw blocking PIDs into the actual queries on both sides of the wait.
SELECT blocked.pid AS blocked_pid,
blocked.query AS blocked_query,
blocking.pid AS blocking_pid,
blocking.query AS blocking_query
FROM pg_stat_activity AS blocked
JOIN LATERAL unnest(pg_blocking_pids(blocked.pid)) AS b(pid) ON true
JOIN pg_stat_activity AS blocking ON blocking.pid = b.pid
WHERE cardinality(pg_blocking_pids(blocked.pid)) > 0;Locks that are still waiting
Every lock a backend has requested but not yet been granted.
SELECT l.pid,
l.locktype,
l.mode,
l.granted,
COALESCE(c.relname, l.transactionid::text) AS object
FROM pg_locks l
LEFT JOIN pg_class c ON c.oid = l.relation
WHERE NOT l.granted
ORDER BY l.pid;Why it happens
What PostgreSQL is telling you
The mechanism behind the error, grounded in the official manual — not paraphrased.
PostgreSQL 16 Documentation — Appendix C, SQL Key Words
Even reserved key words are not completely reserved in PostgreSQL, but can be used as column labels (for example, SELECT 55 AS CHECK, even though CHECK is a reserved key word).Read the full section on postgresql.org →
The unquoted CREATE TABLE
order is a reserved key word in PostgreSQL's grammar. Used unquoted as a table name, the parser saw it as a key word, not an identifier, and rejected the statement before any table was created.Confirming nothing was created
pg_tables confirms no table named order exists — the rejected statement had no effect at all.Reproduce & verify
A real, single-session PostgreSQL reproduction
A literal transcript of SQL run against a live PostgreSQL instance in an isolated lab — the commands below are exactly what was executed.
- 1Try to CREATE TABLE using a reserved SQL key word as the name, without quoting it.
- 2PostgreSQL's parser rejects the statement before it reaches table creation.
- 3SQLSTATE 42601 is reported, pointing at the exact token that broke parsing.
One client: CREATE TABLE using a reserved word as the table name, unquoted.
-- No table needed: the failure happens purely at the parser stage.
SELECT 'no schema required' AS setup_note;CREATE TABLE order (id int);SELECT count(*) FROM pg_tables WHERE tablename = 'order';What PostgreSQL actually returned
setup_note
--------------------
no schema required
(1 row)ERROR: syntax error at or near "order"
LINE 1: CREATE TABLE order (id int);
^ count
-------
0
(1 row)The manual states that even reserved key words can still be used as column labels. This was tested directly, using CHECK — the manual's own example.
Use a reserved key word as a column label with AS, exactly as the manual's example shows.
Without this
Above: order used as a table name, unquoted, is rejected.
With this, tested
Below: a reserved key word used as a column label, not an identifier, works fine.
What Pro unlocks here
- The exact prevention SQL — copy-paste ready
- Raw psql output captured from the Docker lab
- A senior-DBA action list to take it further
- Live monitoring queries to catch it in production
- The deeper audit: fix-that-fails counterexample, GUC before/after, server-log evidence
Related & next steps
Follow the thread
Everything this error touches — jump straight to the sibling error, term, runbook, or parameter.
Verification
- Last verified
- 2026-07-16 (Docker lab, PostgreSQL 16.14)
- Reviewed by
- Verified against PostgreSQL 16.14 in an isolated lab environment
- Audit status
- reviewed