Incident brief
Value too long for character varying(n)
A string was too long to fit in a length-limited column. PostgreSQL rejects it — except in one narrow case the manual calls out by name.
In 10 seconds
- What
- Value too long for character varying(n)
- What triggers it
- Create a table with a varchar(5) column.
- The fix
- Widen the column if longer values are genuinely valid data.
- Proof
- Reproduced on PostgreSQL 16.14 → Inserting 'toolongname' (11 characters) into a varchar(5) column was rejected with SQLSTATE 22001. No row was stored.
The fix
What to do right now
The immediate, application-level response to this error.
- Widen the column if longer values are genuinely valid data.
- Validate or trim the string length in the application before inserting.
- Use text instead of a length-limited type when there's no real limit to enforce.
-- widen the column so a legitimately longer value fits
ALTER TABLE growth.beta_signups ALTER COLUMN username TYPE varchar(20);
INSERT INTO growth.beta_signups (id, username) VALUES (4, 'toolongname');Diagnose
See it live on the server
Run these against the affected instance to confirm the diagnosis before you act.
Standard triage — not specific to this error
These are canonical PostgreSQL system-catalog queries, shown as SQL to run. No sample output is attached because this is general triage, not a captured lab transcript.This SQLSTATE does not have an error-specific live snapshot yet. These are the canonical system-catalog queries you run against the affected server to see the problem in real time — standard triage, not a reproduced transcript.
What is running right now
Active backends, how long each has been running, and what it is waiting on.
SELECT pid,
state,
wait_event_type,
wait_event,
now() - query_start AS running_for,
left(query, 80) AS query
FROM pg_stat_activity
WHERE state <> 'idle'
AND pid <> pg_backend_pid()
ORDER BY running_for DESC NULLS LAST;Who is blocking whom
Turn raw blocking PIDs into the actual queries on both sides of the wait.
SELECT blocked.pid AS blocked_pid,
blocked.query AS blocked_query,
blocking.pid AS blocking_pid,
blocking.query AS blocking_query
FROM pg_stat_activity AS blocked
JOIN LATERAL unnest(pg_blocking_pids(blocked.pid)) AS b(pid) ON true
JOIN pg_stat_activity AS blocking ON blocking.pid = b.pid
WHERE cardinality(pg_blocking_pids(blocked.pid)) > 0;Locks that are still waiting
Every lock a backend has requested but not yet been granted.
SELECT l.pid,
l.locktype,
l.mode,
l.granted,
COALESCE(c.relname, l.transactionid::text) AS object
FROM pg_locks l
LEFT JOIN pg_class c ON c.oid = l.relation
WHERE NOT l.granted
ORDER BY l.pid;Why it happens
What PostgreSQL is telling you
The mechanism behind the error, grounded in the official manual — not paraphrased.
PostgreSQL 16 Documentation — §8.3 Character Types
An attempt to store a longer string into a column of these types will result in an error, unless the excess characters are all spaces, in which case the string will be truncated to the maximum length.Read the full section on postgresql.org →
The insert that's too long
PostgreSQL measured the string at 11 characters against the column's 5-character limit and rejected the insert outright.Checking the table afterward
The table is empty. The rejected insert left no truncated or partial row behind.Reproduce & verify
A real, single-session PostgreSQL reproduction
A literal transcript of SQL run against a live PostgreSQL instance in an isolated lab — the commands below are exactly what was executed.
- 1Create a table with a varchar(5) column.
- 2Insert a plain string longer than 5 characters.
- 3PostgreSQL rejects it with SQLSTATE 22001 instead of storing a cut-off value.
One client: create a varchar(5) column, insert a plain string that's too long for it.
DROP TABLE IF EXISTS growth.beta_signups;
CREATE TABLE growth.beta_signups (
id integer primary key,
username varchar(5)
);INSERT INTO growth.beta_signups (id, username) VALUES (1, 'toolongname');SELECT * FROM growth.beta_signups;What PostgreSQL actually returned
DROP TABLE
CREATE TABLEERROR: value too long for type character varying(5) id | username
----+----------
(0 rows)The manual's own exception was tested directly: an explicit cast to varchar(5) truncates an over-length value instead of raising an error — a different behavior from the plain insert above.
Insert the same over-length string again, but this time cast it explicitly to varchar(5) first.
Without this
Above: a plain insert with no cast raises SQLSTATE 22001.
With this, tested
Below: the same value, explicitly cast to varchar(5), is silently truncated to 5 characters instead.
What Pro unlocks here
- The exact prevention SQL — copy-paste ready
- Raw psql output captured from the Docker lab
- A senior-DBA action list to take it further
- Live monitoring queries to catch it in production
- The deeper audit: fix-that-fails counterexample, GUC before/after, server-log evidence
Related & next steps
Follow the thread
Everything this error touches — jump straight to the sibling error, term, runbook, or parameter.
Related errors
Verification
- Last verified
- 2026-07-16 (Docker lab, PostgreSQL 16.14)
- Reviewed by
- Verified against PostgreSQL 16.14 in an isolated lab environment
- Audit status
- reviewed