PG
PRO
22001ERRORTier 1 — Safe✅ HIGH confidence

value too long for type character varying

Category: Data ExceptionVersions: All Postgres versions

What this means

An attempt was made to store a string value into a VARCHAR(n) or CHAR(n) column where the string's length in characters exceeds the declared limit n. Postgres enforces this limit in the executor before writing to the heap.

Why it happens

  1. 1Input data is longer than the column's declared character limit
  2. 2Column length was reduced with ALTER TABLE ALTER COLUMN TYPE without checking existing data
  3. 3Multibyte UTF-8 characters being counted incorrectly at the application layer (byte length vs character length)
  4. 4Truncation that was expected to happen silently (as in some other databases) does not occur in Postgres by default

How to reproduce

An INSERT attempts to store a 12-character string in a VARCHAR(10) column.

trigger — this will ERROR
CREATE TABLE products (
  id   SERIAL PRIMARY KEY,
  code VARCHAR(10) NOT NULL
);

INSERT INTO products (code) VALUES ('TOOLONGVALUE'); -- 12 chars, limit is 10
ERROR: value too long for type character varying(10)

Fix 1: Increase the column length limit

When the data is legitimately longer than the original limit and the schema should be relaxed.

fix
ALTER TABLE products ALTER COLUMN code TYPE VARCHAR(50);

Why this works

Increasing a VARCHAR(n) limit in Postgres does not rewrite the table; it only updates the pg_attribute entry when the new limit is larger than the old one. The executor checks the new limit on subsequent writes. This is an O(1) metadata-only change.

Fix 2: Change to TEXT (no length limit)

When there is no meaningful business constraint on length and VARCHAR was used out of habit.

fix
ALTER TABLE products ALTER COLUMN code TYPE TEXT;

Why this works

TEXT and VARCHAR without a limit are stored identically in Postgres (both use the varlena storage format). There is no performance difference. Switching to TEXT removes the length check from the executor entirely.

Fix 3: Truncate the input value in the query

When the business rule requires enforcing the limit by truncating rather than rejecting.

fix
INSERT INTO products (code)
VALUES (LEFT('TOOLONGVALUE', 10)); -- truncates to 'TOOLONGVAL'

Why this works

LEFT(str, n) returns the first n characters. The truncation happens in executor expression evaluation before the tuple is formed, so the stored value satisfies the column limit.

What not to do

Cast the value to VARCHAR without a limit to bypass the error

Why it's wrong: The cast succeeds in the expression but the column constraint still applies at insert time; use ALTER TABLE to fix the schema.

Sources

📚 Official docs: https://www.postgresql.org/docs/current/errcodes-appendix.html

📚 Feature docs: https://www.postgresql.org/docs/current/datatype-character.html

🔧 Source ref: src/backend/utils/adt/varchar.c — varchar()

📖 Further reading: Character Types

Confidence assessment

✅ HIGH confidence

Highly stable and well-documented. The behaviour of VARCHAR(n) is defined by the SQL standard. Edge case: CHAR(n) pads short values with spaces; values longer than n that consist only of trailing spaces are silently truncated, but otherwise 22001 is raised.

See also

⚙️ This error reference was generated with AI assistance and reviewed for accuracy. Examples are provided to illustrate common scenarios and may not cover every case. Always test fixes in a development environment before applying to production. Spotted an error? Suggest a correction →