When a SUBSTRING call receives arguments that violate SQL standard rules, PostgreSQL raises:
ERROR: negative substring length not allowed
SQLSTATE: 22011
The condition name is substring_error, and it belongs to SQLSTATE class 22 — Data Exception. This error surfaces when the length argument to SUBSTRING is negative or otherwise invalid per the SQL standard.
What This Error Means
SQLSTATE class 22 covers errors that arise from invalid data values, not from syntax or schema problems. Within that class, 22011 specifically targets string-function argument violations in SUBSTRING (and its SQL-standard form SUBSTRING(string FROM start FOR length)).
PostgreSQL raises this error synchronously during query execution when it evaluates the SUBSTRING expression with a negative length. The SQL standard forbids a negative length argument in SUBSTRING(string FROM start FOR length) — the length operand must be a non-negative integer. PostgreSQL enforces this strictly.
The error causes the current statement to fail. In an explicit transaction block, the transaction is placed in an aborted state and all subsequent commands will fail until you issue ROLLBACK (or ROLLBACK TO SAVEPOINT if you used a savepoint). Outside a transaction block, only the single statement is rolled back.
Note that SUBSTRING with only a start position and no length argument (SUBSTRING(string FROM start)) does not trigger this error — it simply returns the rest of the string from that position.
Common Causes
Passing a negative integer literal as the length argument. For example:
SUBSTRING('hello' FROM 2 FOR -1)— theFOR -1part violates the standard and raises22011.Computing the length from a formula that can go negative. A common pattern is
SUBSTRING(col FROM pos FOR end_pos - pos). Ifend_posis less thanpos, the computed length is negative and the error fires at runtime even though the query looks correct statically.User-supplied input passed directly into the length argument. If application code accepts a user-provided length and passes it without validation, a negative or zero value can reach the database.
Off-by-one arithmetic in dynamic SQL. Stored procedures or functions that compute substring boundaries from column data can produce a negative length when the source data does not match the expected format.
How to Fix substring_error
Guard the length with
GREATEST(0, ...).
Wrap the computed length so it never goes below zero:-- Instead of this: SELECT SUBSTRING(col FROM start_pos FOR end_pos - start_pos) FROM t; -- Use this: SELECT SUBSTRING(col FROM start_pos FOR GREATEST(0, end_pos - start_pos)) FROM t;A length of
0returns an empty string, which is usually the correct behavior when the range is empty.Add an explicit check before calling
SUBSTRING.
Use aCASEexpression to short-circuit when the length would be negative:SELECT CASE WHEN end_pos > start_pos THEN SUBSTRING(col FROM start_pos FOR end_pos - start_pos) ELSE '' END FROM t;Validate inputs in application code before they reach SQL.
If the length comes from user input or an API parameter, enforcelength >= 0at the application layer before constructing the query.Use the two-argument form when you only need a start offset.
If you do not actually need to limit the length, omit theFOR lengthclause entirely:-- Returns everything from position 3 onward — no length restriction: SELECT SUBSTRING(col FROM 3) FROM t;Use
SUBSTRfor zero-based or length-optional slicing.
TheSUBSTR(string, start, length)function is an alias that behaves identically toSUBSTRING ... FROM ... FOR ...and raises the same error for a negative length, but is sometimes clearer in intent. The fix is the same.Catch the error in PL/pgSQL with an exception handler when the negative length is an expected edge case:
DO $$ DECLARE result text; BEGIN result := SUBSTRING('hello' FROM 3 FOR -1); EXCEPTION WHEN substring_error THEN result := ''; END; $$;
Additional Information
- SQLSTATE
22011is part of class22(Data Exception). Related conditions in the same class include22001(string_data_right_truncation),22003(numeric_value_out_of_range), and22012(division_by_zero). - The SQL standard (
ISO/IEC 9075) defines thesubstring_errorcondition. PostgreSQL has conformed to this behavior since early versions; there is no version-specific change to be aware of for production PostgreSQL (9.x and later). - The condition name
substring_errorcan be used directly in PL/pgSQLEXCEPTION WHENclauses without knowing the SQLSTATE code. - Most PostgreSQL drivers (libpq, psycopg2, asyncpg, JDBC) surface this as a
DataErroror equivalent class, with the SQLSTATE22011available in the exception object. - ORMs such as SQLAlchemy will raise
sqlalchemy.exc.DataErrorwrapping the original22011message. The original message (negative substring length not allowed) is typically included in the exception string.
Frequently Asked Questions
Why does PostgreSQL reject a negative length when other databases silently return an empty string?
PostgreSQL follows the SQL standard strictly: the standard specifies that a negative length argument is an error. Some databases (e.g., MySQL's SUBSTRING) treat a negative or zero length as returning an empty string silently. If you are migrating SQL from MySQL to PostgreSQL, this difference can cause runtime failures that were not visible before.
Does this error only apply to the SUBSTRING function?
Yes. SQLSTATE 22011 is specifically tied to the SUBSTRING / SUBSTRING ... FROM ... FOR ... family. Other string functions that receive invalid arguments raise different SQLSTATE codes (for example, REPEAT with a negative count returns an empty string rather than an error, and OVERLAY with a negative length raises 22011 as well since it uses similar SQL-standard substring mechanics internally).
Can I reproduce this error deterministically for testing?
Yes:
SELECT SUBSTRING('test' FROM 1 FOR -1);
-- ERROR: negative substring length not allowed
-- SQLSTATE: 22011
Will wrapping in GREATEST(0, length) affect performance?
No. The GREATEST function on two integer arguments is essentially free — it compiles to a single comparison instruction. There is no meaningful performance difference compared to the unguarded call.