# 22021 — character_not_in_repertoire

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

# 22021

## At a glance {#at-a-glance}
A source byte sequence is invalid for the encoding being checked. The fixed conversion path reports `invalid byte sequence for encoding "%s": %s` and formats the offending bytes.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `22021` |
| Condition | `character_not_in_repertoire` |
| 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_CHARACTER_NOT_IN_REPERTOIRE` |
| Aliases | `—` |

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

## Meaning {#meaning}
`report_invalid_encoding` computes the incomplete or invalid multibyte length and emits 22021 with the source encoding name and hexadecimal bytes. A valid source character that has no equivalent in the destination encoding follows the separate `22P05` untranslatable-character path; that is not evidence that the source bytes themselves are malformed.

## Diagnosis {#diagnosis}
Record source and destination encodings, client/database settings, and the exact bytes before changing anything. Invalid source bytes point to input or boundary decoding; a readable but unrepresentable character points to conversion repertoire. Do not treat SQL_ASCII as a universal fix: accepting arbitrary bytes can defer or hide an encoding boundary defect.

## Response {#response}
Repair the producer or encoding boundary, or explicitly convert the value with a deliberate loss/rejection policy while retaining the offending bytes for diagnosis. If the ERROR occurred in an explicit transaction, roll back or roll back to the existing savepoint before retrying; autocommit can retry corrected input.

## Versions {#versions}
The locked catalogue records this condition from 7.4; the fixed conversion paths here are PostgreSQL 18.6. No natural runtime observation is claimed for this page.

## Related {#related}
[`22P05`](../22p05/), [`22018`](../22018/)

## Sources {#sources}
The invalid-byte reporter is [`src/backend/utils/mb/mbutils.c#L1818-1853`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/mb/mbutils.c#L1818); the same fixed file’s [`report_untranslatable_char` path](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/mb/mbutils.c#L1861) emits the distinct 22P05 condition for a valid but non-representable character. The structured [evidence record](../data/evidence/22021.json) retains both boundaries; no natural runtime was run.
