Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for Postgres By James Joyner IV · · 8 min read Last reviewed Jul 2026

PostgreSQL Error Guide: 'value too long for type character varying(n)' — Fix

Quick answer

Fix 'value too long for type character varying(n)' in Postgres: find the oversized string, decide between widening the column or truncating input, and handle multibyte length gotchas, with real SQL.

Part of the PostgreSQL Database Errors hub
  • #postgres
  • #database
  • #troubleshooting
  • #errors
Free toolkit

Stuck on this Postgres error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Overview

PostgreSQL raises this when a string being stored exceeds the declared length of a varchar(n) (or char(n)) column:

ERROR:  value too long for type character varying(50)

Unlike some errors, this one does not name the column or the value — it only tells you the type and its limit. Finding which column and which row overflowed is the first diagnostic task.

Symptoms

  • An INSERT/UPDATE fails when user input, imported data, or a generated string is longer than the column allows.
  • A migration copying data into a narrower column aborts partway.
  • A COPY import stops on the first oversized row.
  • An ORM save fails only for records with long text (a long name, URL, or description).
  • The same value succeeds in one table and fails in another because the column widths differ.

Common Root Causes

  • Column declared too narrow — a varchar(50) that was fine until real-world data (long email addresses, international names, URLs) exceeded it.
  • Input not validated for length at the application layer, so an over-long string reaches the database.
  • Concatenation or formatting produced a longer string than expected (prefixes, joined values, encoded tokens).
  • Migration into a narrower column — copying from text or a wider varchar into a smaller one.
  • Multibyte characters — the count is characters, not bytes, so this isn’t a byte-length surprise, but an emoji or accented text can still push a nominally short string over the character limit.
  • Trailing whitespace or hidden characters inflating the length beyond what’s visually apparent.
  • A generated column or trigger building a value that overflows the target width.

Diagnostic Workflow

The message gives you the type and limit (character varying(50)) but not the column. Find candidate columns of that width:

SELECT table_name, column_name, character_maximum_length
FROM information_schema.columns
WHERE data_type = 'character varying'
  AND character_maximum_length = 50
  AND table_name = 'users';

Once you suspect a column, find the offending rows by length. For an existing-data migration, run this against the source:

SELECT id, char_length(full_name) AS len, full_name
FROM source_users
WHERE char_length(full_name) > 50
ORDER BY len DESC
LIMIT 50;

For an application insert, log the failing statement and parameters to capture the actual value:

SET log_min_error_statement = 'error';

Check for trailing whitespace or hidden characters inflating the length:

SELECT id, char_length(code), char_length(rtrim(code)) AS trimmed_len, code
FROM items
WHERE char_length(code) > char_length(rtrim(code));

See the exact width of every text column on the table:

\d+ users

Example Root Cause Analysis

A user-import job failed with value too long for type character varying(32). The message named neither column nor value, so the first step was to find columns of width 32 on the target table:

SELECT column_name, character_maximum_length
FROM information_schema.columns
WHERE table_name = 'users' AND character_maximum_length = 32;
 column_name | character_maximum_length
-------------+--------------------------
 phone       |                       32
 country     |                       32

Two candidates. Testing the source data for each:

SELECT id, char_length(phone), phone FROM import_users WHERE char_length(phone) > 32;
-- (0 rows)
SELECT id, char_length(country), country FROM import_users WHERE char_length(country) > 32;
 id   | char_length | country
------+-------------+------------------------------------------
 9021 |          41 | United Kingdom of Great Britain and ...

The country column was declared varchar(32) on the assumption of short country codes, but the import carried full official country names. The decision was to widen the column — country names are legitimately long, so truncating would lose data:

ALTER TABLE users ALTER COLUMN country TYPE varchar(100);

Widening a varchar to a larger length is a metadata-only change in modern Postgres and does not rewrite the table, so it was fast even on a large table.

Prevention Best Practices

  • Size varchar(n) limits to real-world data, not optimistic guesses; when in doubt, use text (unbounded) or a generous limit — there is no storage or performance penalty for text versus varchar in Postgres.
  • Validate input length at the application boundary and return a clear error instead of letting the database reject it.
  • Before migrating into a narrower column, run the char_length(col) > n query on the source and decide widen-vs-truncate deliberately.
  • Prefer widening (ALTER COLUMN ... TYPE varchar(bigger), a fast metadata change) over silent truncation, which loses data.
  • If truncation is genuinely acceptable, do it explicitly with left(value, n) so intent is clear and logged.
  • Trim whitespace on input so trailing spaces don’t consume the length budget.

Quick Command Reference

-- Find columns of a given varchar width
SELECT table_name, column_name, character_maximum_length
FROM information_schema.columns
WHERE data_type = 'character varying' AND character_maximum_length = 50;

-- Find rows that exceed the limit (in source data)
SELECT id, char_length(col), col FROM source WHERE char_length(col) > 50 ORDER BY 2 DESC;

-- Widen the column (metadata-only, no table rewrite)
ALTER TABLE users ALTER COLUMN country TYPE varchar(100);

-- Or convert to unbounded text
ALTER TABLE users ALTER COLUMN country TYPE text;

-- Explicit, intentional truncation on input
SELECT left(trim(value), 50) FROM staging;

Conclusion

This error is Postgres enforcing a declared width, and the annoyance is that the message names only the type — not the column or value — so the first move is to list columns of that width and hunt the oversized rows with char_length. The right fix is usually to widen the column (a fast metadata-only change) rather than truncate and lose data, and to size limits for real-world input in the first place. Remember that text is free in Postgres, so unless a hard length rule exists, an unbounded text column avoids the whole class of failure.

Free download · 368-page PDF

Fixed it? Get 500 Postgres & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.