Skip to content

42601 — syntax_error

PostgreSQL SQLSTATE 42601: syntax_error, source-backed diagnosis and recovery guidance.

42601

At a glance

SQLSTATE 42601 is syntax_error in Class 42. 42601 is a syntax error. The selected parser path rejects LIMIT 1, 2 with primary LIMIT #,# syntax is not supported and hint Use separate LIMIT and OFFSET clauses.

Field Value
SQLSTATE 42601
Condition syntax_error
Status active
Known present by 7.4
Locked snapshots 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3
Macros ERRCODE_SYNTAX_ERROR
Aliases

Meaning

42601 is a syntax error. In the selected gram.y action, the comma form is rejected during parsing with the ERROR primary LIMIT #,# syntax is not supported and hint Use separate LIMIT and OFFSET clauses. The comma form is therefore not a request for “offset 1, then take 2” in PostgreSQL; the two values must be written as separate clauses.

The scanner and grammar share a general 42601 path. scanner_yyerror sets the SQLSTATE and reports either syntax error at or near "%s" for the current token or syntax error at end of input when the scanner is at the buffer end, with a lexer position. Grammar actions can supply a more specific message through the same formatter. The selected LIMIT branch is one producer among these parser and scanner branches, not a requirement for every 42601.

Diagnosis

Capture the exact statement, parser position, server version, and hint. For at or near, inspect the token named by POSITION and the text immediately before it; for at end of input, check an unclosed quote, dollar-quote, parenthesis, comment, or generated clause. Preserve the exact bytes sent by the query builder, including delimiters and substituted fragments, and replay that statement through the server parser before changing semantics. The parser rejects this grammar before execution, so the selected autocommit session remains IDLE and no rows are produced by the failed statement. In an explicit transaction, the same statement-level ERROR leaves the transaction in its failed state until ROLLBACK or an appropriate savepoint action; that is a different session boundary from the selected autocommit observation. Do not confuse a grammar error with an undefined object or a feature recognized but unsupported in its context.

Response

Rewrite the statement using the grammar named by the hint. For the selected ordered three-row query, LIMIT 1, 2 becomes LIMIT 2 OFFSET 1 and returns rows [2, 3]; LIMIT 1 OFFSET 0 would be a different result and is not an equivalent repair. Keep query builders version-aware when they emit dialect-specific pagination.

For a generic scanner error, repair the missing or misplaced token, quote, comment delimiter, or query-builder fragment identified by the position, then parse the complete statement again. Do not apply the LIMIT rewrite to a different 42601 message merely because it shares the SQLSTATE.

Messages

The selected parser branch raises an explicit ERROR with primary LIMIT #,# syntax is not supported and HINT Use separate LIMIT and OFFSET clauses. The scanner’s generic fixed branches use syntax error at or near "%s" or syntax error at end of input, with the position generated from the lexer. The LIMIT primary/HINT identify the selected pagination subpath; a client exception without the server SQLSTATE and the diagnostics for the specific branch is not sufficient to identify that subpath, while other valid 42601 producers may have different primaries.

Representative case

The page uses the same statements as the runner registry. Generated names such as syntax_schema and syntax_role are replaced by disposable runner values when executed.

SELECT n FROM generate_series(1, 3) AS s(n) ORDER BY n LIMIT 1, 2;
SELECT n FROM generate_series(1, 3) AS s(n) ORDER BY n LIMIT 2 OFFSET 1;

The selected 18.6 run reports the structured diagnostic and passes the repair assertions; the 10.21 run passes the same case-specific checks. The downloadable case and evidence projections are 42601 case JSON and authored evidence. The runner manifest is verify/cases/42601/cases.json, and the page SQL is checked against its shared registry.

Versions

The selected natural runtime scope is PostgreSQL 18.6 and 10.21; it does not infer behavior for every intermediate release.

Sources

  • src.errcodes.18.6 — fixed errcodes.txt definition at commit 724edf9bde9d356724ad384a2e196edc3c9f80f7; SHA-256 6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba (source).
  • src.limit-comma.18.6src/backend/parser/gram.y at REL_18_6 commit 724edf9bde9d356724ad384a2e196edc3c9f80f7; fixed blob SHA-256 7e548b673a1e03eb3a56c5eb9ad92d8e11095fac76e14cb258ca851f58274724 (source).
  • src.limit-comma.10.23src/backend/parser/gram.y at REL_10_23 commit 02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4; fixed blob SHA-256 cebad6a5a2bdf68e9e5a4d2e04fa7f5dbf37efac99f5edb73cc661dae1536bad (source).
  • src.scanner-syntax.18.6 / src.scanner-syntax.10.23 — fixed src/backend/parser/scan.l scanner_yyerror branches for at end of input and at or near; blob SHA-256 bf453f1ae3c22b84fea6f8e8bed4fda476b7cfa49b234efbf92ca228234d0293 / a006581a25c659d59b29837010617503ff431f881e3cf0b54a99aa1cc445fe6c (18.6 source, 10.23 source).
  • src.calls.REL_18_6 / src.calls.REL_10_23 — fixed call scans, SHA-256 9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf / 00d16d3eb01b71ccf1b245c8f3102f9d0ec9f36fb02777b8dd1b99fcb263040c.