54011 — too_many_columns
54011
At a glance
54011 reports that a physical tuple descriptor or a related object definition exceeds its fixed column limit. The source path determines whether the count is for table attributes, index keys plus INCLUDE columns, partition keys, statistics dimensions, or a row-producing definition.
| Field | Value |
|---|---|
| SQLSTATE | 54011 |
| Condition | too_many_columns |
| Status | active |
| Known present by | 7.4 |
| Locked snapshots | 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3 |
| Macros | ERRCODE_TOO_MANY_COLUMNS |
| Aliases | — |
Meaning
Fixed messages include number of columns (%d) exceeds limit (%d), tables can have at most %d columns, cannot use more than %d columns in an index, cannot partition using more than %d columns, and statistics-specific forms. Table counts operate on physical attribute numbers: a dropped column still occupies a tuple-descriptor slot, so the visible-column count can be lower than relnatts. Index key and INCLUDE entries, partition keys, and statistics dimensions use separate limits even though all use this SQLSTATE.
In the locked 18.6 build, the relevant constants are MaxHeapAttributeNumber = 1600 user table attributes, MaxTupleAttributeNumber = 1664 tuple attributes, INDEX_MAX_KEYS = 32, PARTITION_MAX_KEYS = 32, and STATS_MAX_DIMENSIONS = 8. These values belong to different guards; the actual count and limit fields in a server diagnostic remain authoritative.
Diagnosis
Read the object type, actual count, maximum, and DDL operation from the message and context. For a table or inherited table, inspect pg_class.relnatts and pg_attribute, including attisdropped, rather than counting only visible names. For an index include INCLUDE columns in the DDL count; for partitioning and extended statistics use their own key/dimension counts. A function-in-FROM column definition list is another 54011 path with a row-shape limit.
Response
Reduce or split the object definition, use a different index or partitioning design, or move derived data to a related table. If dropped physical slots are the cause, dropping another visible column will not reclaim them; an ordinary physical rewrite such as VACUUM FULL or CLUSTER also keeps the dropped attributes in the tuple descriptor. Plan a new table with the intended logical column layout, migrate data while preserving dependencies, and validate DDL against the named object limit. If an ERROR occurs inside an explicit transaction, use ROLLBACK or ROLLBACK TO SAVEPOINT before retrying; in autocommit, retry only after the schema change removes the actual limit.
Versions
The locked catalogue records this condition from 7.4; cited heap, index, table, partition, statistics, and row-shape paths are PostgreSQL 18.6 source. No oversized schema was created.
Related
Sources
src/backend/access/common/heaptuple.c#L1131-L1134
src/backend/access/common/indextuple.c#L87-L90
src/backend/catalog/heap.c#L461-L464
src/backend/commands/tablecmds.c#L2567-L2582
src/backend/commands/indexcmds.c#L640-L664
src/backend/commands/statscmds.c#L215-L224
src/backend/parser/parse_relation.c#L1935-L1946
src/include/access/htup_details.h#L34-L48
src/include/pg_config_manual.h#L63-L74
src/include/statistics/statistics.h#L19
The structured evidence record records fixed messages and the source/runtime boundary.