PostgreSQL error 42601 (Syntax Error) explained: what it means, why it happens, and how to fix it — with copy-paste code examples.
Read the caret position in the error to find the exact token. If that does not apply, quote identifiers with double quotes and string literals with single quotes — the full checklist is below.
SQLSTATE: 42601
Official name: Syntax Error
System name: syntax_error
Service: PostgreSQL
The SQL statement contains a syntax error and could not be parsed.
You may see this error reported as one of the following messages:
syntax error at or near "SELET"syntax error at end of inputAn app builds SQL by string concatenation and a missing space produces SELECT * FROMusers WHERE id = 1. psql answers: ERROR: syntax error at or near "FROMusers" — the token quoted in the message is where the parser stopped, which is usually one token AFTER the actual mistake. The same error appears for a trailing comma in a SELECT list or a missing closing quote.
Run these to confirm the cause before applying a fix — each command answers a specific question.
-- run the failing statement verbatim in psql;
-- the 'at or near' token marks the parse failure point,
-- which is usually just AFTER the actual mistake.
Inspect the quoted token and the one immediately before it; most 42601s are a missing space, comma, quote, or parenthesis there.
-- log the exact statement the server received
SET client_min_messages = log;
-- or in the app: print the SQL string AFTER parameter binding
If the logged SQL looks fine but the server still fails, check for invisible characters copied from docs or chat.
Parser points at a keyword (FROM/WHERE/ORDER)?
├─ missing space or parenthesis one token earlier
└─ reserved word used as an alias → rename or double-quote it
Parser points at a string/value?
├─ unterminated single quote → escape '' or use parameters
└─ double quotes vs single quotes: "name" = identifier, 'x' = string
Statement looks perfect?
└─ check invisible characters / copy-paste artifacts (zero-width space)
-- WRONG: double quotes are identifiers
SELECT "name" FROM "users" WHERE email = "a@b.com";
-- RIGHT: single quotes are string literals
SELECT name FROM users WHERE email = 'a@b.com';
Double quotes denote identifiers (table/column names); single quotes denote string values. Mixing them is the most common cause of 42601.
Use ORM methods or raw() with params; never f-string SQL.
MyModel.objects.raw('SELECT * FROM t WHERE id = %s', [pk])
Use the text() construct with bound params to avoid syntax errors from interpolation.
from sqlalchemy import text
session.execute(text('SELECT * FROM users WHERE id = :id'), {'id': pk})
Use the query builder or .rpc() with params rather than building SQL strings.
const { data } = await supabase.from('users').select().eq('id', pk)
Most often this happens when missing comma, parenthesis, or keyword in hand-written SQL, or when using double quotes for strings instead of single quotes.
Read the caret position in the error to find the exact token.
This page documents fixes for: django, sqlalchemy, supabase.
Recommendations are editorial — DB Error Reference takes no payment or affiliate fees for tool listings.
This page is based on the official PostgreSQL documentation linked below and adds practical troubleshooting guidance on top.