ERROR: value too long for type character varying(20) (SQLSTATE 22001) means
you tried to store a string longer than the column's declared limit. PostgreSQL rejects
the whole row instead of cutting the string. Widen the column, or validate the length
before you insert.
The message names the type and its limit but not the column, so look for the column
declared with that length. ALTER TABLE ... ALTER COLUMN ... TYPE varchar(100)
(or plain text) fixes it when the data is legitimate.
The error
INSERT INTO contacts (full_name, country) VALUES ('Maria Fernanda Garcia Lopez', 'ES');
psql:/tmp/p7.sql:8: ERROR: value too long for type character varying(20)
The same rule applies to char(n), with its own type name in the message:
INSERT INTO contacts (full_name, country) VALUES ('David Chen', 'CAN');
psql:/tmp/p7.sql:10: ERROR: value too long for type character(2)
Why it happens
varchar(20) is a promise that no value in the column is longer than 20
characters. 'Maria Fernanda Garcia Lopez' has 27, so the insert fails. There
is no DETAIL line and no column name in the message, which makes it hard to
find in a wide insert; compare the number in the message with the column definitions
(\d contacts in psql).
Two exceptions catch people out. An explicit cast truncates silently instead of failing:
SELECT 'Maria Fernanda Garcia Lopez'::varchar(20) returned
Maria Fernanda Garci. And extra characters that are all spaces are trimmed
instead of rejected: 'CA ' went into char(2) as
CA without an error.
The fix
ALTER TABLE contacts ALTER COLUMN full_name TYPE varchar(100);
ALTER TABLE
INSERT INTO contacts (full_name, country) VALUES ('Maria Fernanda Garcia Lopez', 'ES');
INSERT 0 1
SELECT id, full_name, length(full_name) AS len FROM contacts;
id | full_name | len
----+-----------------------------+-----
1 | Maria Fernanda Garcia Lopez | 27
(1 row)
Widening a varchar is the right fix for names, addresses and free text: real
names are often longer than a guessed limit. When the limit is a real rule, such as a two-letter country code, keep it and validate the
input instead. Do not cast to varchar(n) to make the error go away; that
loses data silently, as shown above. From .NET, Npgsql raises a
PostgresException with SqlState 22001.
How it was reproduced
A postgres:18 container (PostgreSQL 18.4, Debian build 18.4-1.pgdg13+1) on
Docker 29.9.2, with
contacts (id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY, full_name varchar(20) NOT NULL, country char(2) NOT NULL).
A 27-character name and a three-letter country code each failed; the explicit cast and the
trailing-space insert succeeded as described; after widening the column the same insert
went through. A verbose run printed ERROR: 22001.
Frequently asked
- How do I find which column caused 'value too long for type character varying'?
- The message gives only the type and its length, not the column. Look for columns declared with that length, for example with \d tablename in psql, and compare them with the values in the failing statement.
- How do I increase a varchar length in PostgreSQL?
- Run ALTER TABLE tablename ALTER COLUMN columnname TYPE varchar(100), or change it to text if no limit is needed. Then repeat the insert that failed.
- Does PostgreSQL truncate strings that are too long?
- Not on insert: it raises SQLSTATE 22001. It does truncate when you cast explicitly to varchar(n), and it accepts a value whose extra characters are all spaces, trimming them.
More decoded errors in the Fixes category. For choosing column types and constraints in the first place, see constraints in Database Design for Developers.