# 22001 — string_data_right_truncation

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

# 22001

## At a glance {#at-a-glance}

22001 is `string_data_right_truncation`. The fixed varchar path reports the declared character width, while hstore and varbit have separate variants.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `22001` |
| Condition | `string_data_right_truncation` |
| 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_STRING_DATA_RIGHT_TRUNCATION` |
| Aliases | `—` |

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

The shared case creates `varchar_limits(value varchar(3))`, inserts `'too-long'` to capture 22001, inserts `'ok'` as the repair, and selects the stored value. Send these statements separately in autocommit: the trigger is expected to fail before the repair statement runs. The runner owns object cleanup after the case.

<!-- BEGIN SQLSTATE SNIPPET: varchar_width_overflow -->
```sql
CREATE TABLE varchar_limits (value varchar(3));
INSERT INTO varchar_limits VALUES ('too-long');
INSERT INTO varchar_limits VALUES ('ok');
SELECT value FROM varchar_limits;
```
<!-- END SQLSTATE SNIPPET -->

Calibration observed `character varying(3)` rejecting an overlong value with `value too long for type character varying(3)`; the corrected value `ok` succeeded and both runner autocommit sessions returned to `IDLE`.

## Messages {#messages}

The fixed character and varchar guards raise `ERROR` with primary templates `value too long for type character(%d)` and `value too long for type character varying(%d)`. The hstore and varbit paths use their own primary templates (`string too long for hstore key`, `string too long for hstore value`, and `bit string too long for type bit varying(%d)`). These source groups provide no separate DETAIL or HINT. The selected runtime observed only the varchar template shown above.

## Meaning {#meaning}

`22001` is raised when a value cannot satisfy a string type's length contract. PostgreSQL measures `character(n)` and `character varying(n)` in characters, so a message such as `value too long for type character(%d)` points to the typmod shown in the response. The fixed `varchar.c` path is the server-side check; hstore keys/values and bit strings have separate source paths and messages.

The boundary also depends on how the value reaches the type. The `varchar()` and `bpchar()` functions receive an `isExplicit` flag: an assignment/input conversion rejects excess non-space characters, while an explicit cast to the bounded type can truncate according to PostgreSQL's character-type rules; excess trailing spaces are treated differently from non-space characters. Make that choice explicit before changing storage or input validation.

## Diagnosis {#diagnosis}

Capture `schema_name`, `table_name`, `column_name`, `datatype_name`, `routine`, and the full primary message. Confirm the target type and typmod from the catalog, then measure the actual value in characters rather than bytes. Check whether the value was inserted/assigned, explicitly cast, or passed through an hstore/bit path; those paths do not share identical truncation behavior.

For the common varchar case, compare the non-space suffix with the declared width. A value that only exceeds the width through trailing spaces can follow the character-type truncation rule, while meaningful non-space data should be treated as a rejected contract. The fixed source message is a type-width diagnosis, not a general encoding or network failure.

## Response {#response}

Choose the repair that preserves the data contract: validate and reject overlong input, deliberately widen the column/type, or explicitly cast only when truncation is an accepted business rule. Record the original value and target typmod before truncating; silently cutting identifiers, keys, or audit text can create a different row than the caller intended. The frozen case used autocommit, so the failed statement left the session `IDLE`; inside an explicit transaction, roll back the transaction or use `ROLLBACK TO SAVEPOINT` for a savepoint created before the statement before retrying the corrected value. After changing the input or schema, re-run the conversion and verify the stored character length.

## Versions {#versions}

The locked catalogue records this condition from 7.4 in the listed formal snapshots and 19beta3; fixed source coverage is PostgreSQL 18.6.

## Related {#related}

[`22003`](../22003/) for numeric/range overflow, [`22007`](../22007/) for datetime format errors, and [`22004`](../22004/) for a separate NULL contract.

## Sources {#sources}

The fixed `character(n)` check is [`varchar.c#L300-L313`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/varchar.c#L300-L313), and the `character varying(n)` check is [`varchar.c#L633-L640`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/varchar.c#L633-L640). PostgreSQL 18's [character types](https://www.postgresql.org/docs/18/datatype-character.html) document character-count limits, trailing-space behavior, and explicit casts. The structured [evidence record](../data/evidence/22001.json) pins the source SHA and keeps hstore/varbit variants separate.
