22001ERRORTier 1 — Safe✅ HIGH confidencevalue too long for type character varying
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
- 1Input data is longer than the column's declared character limit
- 2Column length was reduced with ALTER TABLE ALTER COLUMN TYPE without checking existing data
- 3Multibyte UTF-8 characters being counted incorrectly at the application layer (byte length vs character length)
- 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.
CREATE TABLE products (
id SERIAL PRIMARY KEY,
code VARCHAR(10) NOT NULL
);
INSERT INTO products (code) VALUES ('TOOLONGVALUE'); -- 12 chars, limit is 10Fix 1: Increase the column length limit
When the data is legitimately longer than the original limit and the schema should be relaxed.
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.
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.
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
🔗 Related errors
📄 Reference pages