# 22011 — substring_error

> Source-backed reference for PostgreSQL SQLSTATE 22011.
---

## At a glance {#at-a-glance}
A text substring path received an invalid explicit length. In fixed PostgreSQL 18.6 code, `text_substring` reports `negative substring length not allowed` with SQLSTATE `22011`.

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| Field | Value |
| --- | --- |
| SQLSTATE | `22011` |
| Condition | `substring_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_SUBSTRING_ERROR` |
| Aliases | `—` |

<!-- source facts: data/errcodes/22011.json -->
<!-- END SQLSTATE FACTS -->

## Meaning {#meaning}
The three-argument text substring wrapper passes its explicit length to `text_substring`; a negative length reaches the `ERRCODE_SUBSTRING_ERROR` guard. The no-length wrapper instead passes a sentinel with `length_not_specified`, so it returns the remainder and does not enter that negative-length guard. The same code is also used by `OVERLAY` when its start position is non-positive. This evidence is for the text path: bytea, bit-string, and pattern-based substring operations have separate consumers and must be identified from the full diagnostic.

## Diagnosis {#diagnosis}
Check the resolved operation and data type before changing values. For text, distinguish an explicit negative length from a start of zero or less: the source clamps the effective start to one and applies the SQL length adjustment. A start past the end returns an empty string. A large start-plus-length that overflows the 32-bit calculation runs to the end; it is not this error. In `OVERLAY`, a non-positive start uses the same primary, while an overflowing start-plus-length uses `22003` instead.

## Response {#response}
Pass a non-negative explicit text length, or omit the length when the intended result is the remainder. Preserve the intended one-based start semantics and check the actual data type before applying a text-specific repair. This path raises `ERROR`; an explicit transaction must be rolled back or rolled back to an existing savepoint before retrying, while autocommit can retry only the corrected statement.

## Messages {#messages}
- Primary, `ERROR`: `negative substring length not allowed` for the explicit text substring guard and the non-positive `OVERLAY` start guard. There is no fixed DETAIL or HINT on these paths.

## Versions {#versions}
The locked catalogue records this condition from 7.4; fixed source coverage is PostgreSQL 18.6. The cited guards are current-version text and `OVERLAY` paths, not a claim about every substring implementation.

## Related {#related}
[`22000`](../22000/), [`22001`](../22001/), [`22003`](../22003/)

## Sources {#sources}
- [`src/backend/utils/adt/varlena.c#L896-L1010`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/varlena.c#L896-L1010) contains the text wrappers, start adjustment, omitted-length sentinel, explicit negative-length `ERROR`, and end/overflow handling.
- [`src/backend/utils/adt/varlena.c#L1166-L1186`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/varlena.c#L1166-L1186) contains the `OVERLAY` guards and its distinct `22003` overflow branch.

Runtime verification is `not_run`; the source evidence is not a runtime observation. The structured [evidence record](../data/evidence/22011.json) retains the exact primary and source scope.
