↑↓ select↵ open⌫ change scopeOpen full search

PG.CENTER connects PostgreSQL documentation, reference, and ecosystem knowledge. Maintained by Pigsty.

Wiki / SQLSTATE

54011 \u2014 too_many_columns

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.

English manual coverage begins with PostgreSQL 8.1. Source history and runtime observations have their own recorded version boundaries.

Reading PG 18·Select a recorded version

aliases
Unknown
class name
Program Limit Exceeded
condition name
too_many_columns
lang
en
sqlstate
54011

Definition PG 18

54011

At a glance {#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.

Meaning {#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 {#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 {#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 {#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 {#related}

54000, 54023, 54001

Sources {#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.

Compare versions

SQLSTATE evidence and recorded runtime versions

claims · identity
{
  "claim_id": "identity",
  "limits": "",
  "method": "Read fixed definition.",
  "position": 0,
  "runtime": [],
  "sources": [
    "src.errcodes.18.6"
  ],
  "statement": "54011 is too_many_columns in SQLSTATE Class 54."
}
claims · resolved-paths
{
  "claim_id": "resolved-paths",
  "limits": "Source confirmation is not natural runtime.",
  "method": "Read complete fixed source contexts.",
  "position": 1,
  "runtime": [],
  "sources": [
    "src.path.0",
    "src.path.1",
    "src.path.2",
    "src.path.3",
    "src.path.4",
    "src.path.5",
    "src.path.6",
    "src.path.7",
    "src.path.8",
    "src.path.9"
  ],
  "statement": "The cited PostgreSQL 18.6 source paths support the representative resource and object-state mechanisms described."
}
claims · physical-and-object-limits
{
  "claim_id": "physical-and-object-limits",
  "limits": "",
  "method": "Read the complete DDL and parser guards.",
  "position": 2,
  "runtime": [],
  "sources": [
    "src.path.3",
    "src.path.4",
    "src.path.5",
    "src.path.6"
  ],
  "statement": "The table guard counts physical attributes including inherited columns, while index, partition, statistics, and function-row definitions use separate fixed arrays or dimensions."
}
claims · fixed-numeric-limits
{
  "claim_id": "fixed-numeric-limits",
  "limits": "The numeric values are for the locked 18.6 source and do not replace the actual count and limit fields in a future server's diagnostic.",
  "method": "Read the fixed macro definitions used by the guards.",
  "position": 3,
  "runtime": [],
  "sources": [
    "src.path.7",
    "src.path.8",
    "src.path.9"
  ],
  "statement": "The fixed 18.6 limit definitions are 1600 user table attributes, 1664 tuple attributes, 32 index keys, 32 partition-key columns, and 8 extended-statistics dimensions; these values belong to different object paths."
}
claims · history
{
  "claim_id": "history",
  "limits": "",
  "method": "Use catalogue boundary.",
  "position": 4,
  "runtime": [],
  "sources": [
    "src.errcodes.18.6"
  ],
  "statement": "The locked catalogue records 54011 from 7.4; that boundary does not prove exact implementation introduction."
}
messages · message.0
{
  "limits": "",
  "message_id": "message.0",
  "path": "",
  "position": 0,
  "raw": {
    "id": "message.0",
    "primary_template": "number of columns (%d) exceeds limit (%d)",
    "severity_source": "ERROR",
    "sources": [
      "src.path.0"
    ],
    "sqlstate": "54011"
  },
  "severity": "ERROR",
  "sources": [
    "src.path.0"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "number of columns ( ) exceeds limit ( )",
      "position": 0,
      "role": "",
      "template": "number of columns (%d) exceeds limit (%d)"
    }
  ]
}
messages · message.1
{
  "limits": "",
  "message_id": "message.1",
  "path": "",
  "position": 1,
  "raw": {
    "id": "message.1",
    "primary_template": "number of index columns (%d) exceeds limit (%d)",
    "severity_source": "ERROR",
    "sources": [
      "src.path.1"
    ],
    "sqlstate": "54011"
  },
  "severity": "ERROR",
  "sources": [
    "src.path.1"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "number of index columns ( ) exceeds limit ( )",
      "position": 0,
      "role": "",
      "template": "number of index columns (%d) exceeds limit (%d)"
    }
  ]
}
messages · message.2
{
  "limits": "",
  "message_id": "message.2",
  "path": "",
  "position": 2,
  "raw": {
    "id": "message.2",
    "primary_template": "tables can have at most %d columns",
    "severity_source": "ERROR",
    "sources": [
      "src.path.2"
    ],
    "sqlstate": "54011"
  },
  "severity": "ERROR",
  "sources": [
    "src.path.2"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "tables can have at most columns",
      "position": 0,
      "role": "",
      "template": "tables can have at most %d columns"
    }
  ]
}
messages · message.3
{
  "limits": "",
  "message_id": "message.3",
  "path": "",
  "position": 3,
  "raw": {
    "id": "message.3",
    "primary_template": "cannot partition using more than %d columns",
    "severity_source": "ERROR",
    "sources": [
      "src.path.3"
    ],
    "sqlstate": "54011"
  },
  "severity": "ERROR",
  "sources": [
    "src.path.3"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "cannot partition using more than columns",
      "position": 0,
      "role": "",
      "template": "cannot partition using more than %d columns"
    }
  ]
}
messages · message.4
{
  "limits": "",
  "message_id": "message.4",
  "path": "",
  "position": 4,
  "raw": {
    "id": "message.4",
    "primary_template": "cannot use more than %d columns in an index",
    "severity_source": "ERROR",
    "sources": [
      "src.path.4"
    ],
    "sqlstate": "54011"
  },
  "severity": "ERROR",
  "sources": [
    "src.path.4"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "cannot use more than columns in an index",
      "position": 0,
      "role": "",
      "template": "cannot use more than %d columns in an index"
    }
  ]
}
messages · message.5
{
  "limits": "",
  "message_id": "message.5",
  "path": "",
  "position": 5,
  "raw": {
    "id": "message.5",
    "primary_template": "cannot have more than %d columns in statistics",
    "severity_source": "ERROR",
    "sources": [
      "src.path.5"
    ],
    "sqlstate": "54011"
  },
  "severity": "ERROR",
  "sources": [
    "src.path.5"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "cannot have more than columns in statistics",
      "position": 0,
      "role": "",
      "template": "cannot have more than %d columns in statistics"
    }
  ]
}
messages · message.6
{
  "limits": "",
  "message_id": "message.6",
  "path": "",
  "position": 6,
  "raw": {
    "id": "message.6",
    "primary_template": "column definition lists can have at most %d entries",
    "severity_source": "ERROR",
    "sources": [
      "src.path.6"
    ],
    "sqlstate": "54011"
  },
  "severity": "ERROR",
  "sources": [
    "src.path.6"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "column definition lists can have at most entries",
      "position": 0,
      "role": "",
      "template": "column definition lists can have at most %d entries"
    }
  ]
}
sources · src.errcodes.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/utils/errcodes.txt",
  "position": 0,
  "sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
  "source_id": "src.errcodes.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt#L418"
}
sources · src.path.0
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/access/common/heaptuple.c",
  "position": 1,
  "sha256": "3553582c4af3631b8b901c514fe3fed828daa376c374634e5773b1b177befd0b",
  "source_id": "src.path.0",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/access/common/heaptuple.c#L1131"
}
sources · src.path.1
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/access/common/indextuple.c",
  "position": 2,
  "sha256": "47ce16ef7099b6d1de759f9605bcc50d128e1b342d8b70625553f29bca4ade00",
  "source_id": "src.path.1",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/access/common/indextuple.c#L87"
}
sources · src.path.2
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/catalog/heap.c",
  "position": 3,
  "sha256": "e720ee58279590793edd0985b3c910970ef56e7361b8ef92e245370587e02a0e",
  "source_id": "src.path.2",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/catalog/heap.c#L461"
}
sources · src.path.3
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/commands/tablecmds.c",
  "position": 4,
  "sha256": "422dc8e833df4940755973c757e338295822ba3e4c7266c40669f49f96eb15a9",
  "source_id": "src.path.3",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/tablecmds.c#L2567"
}
sources · src.path.4
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/commands/indexcmds.c",
  "position": 5,
  "sha256": "0bdae365f207ab82865806c5983cac94c5c062e7a61ab7c883ccb7e2015fad36",
  "source_id": "src.path.4",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/indexcmds.c#L640"
}
sources · src.path.5
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/commands/statscmds.c",
  "position": 6,
  "sha256": "3cbdc9bfd55c98d0c7543af9d366b8e76d5d3b49661f5634ee5f71bedd2aacdb",
  "source_id": "src.path.5",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/statscmds.c#L215"
}
sources · src.path.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/parser/parse_relation.c",
  "position": 7,
  "sha256": "0d9c88f4a8def4c2d982c33f13208590e21ecf5e6f8cd9d7faa223dc771c9a9a",
  "source_id": "src.path.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/parser/parse_relation.c#L1935"
}
sources · src.path.7
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/include/access/htup_details.h",
  "position": 8,
  "sha256": "175dad20a31eea61d724bf2954457dc09d4635e552ba63b2ac1cf1c9508c0626",
  "source_id": "src.path.7",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/include/access/htup_details.h#L34"
}
sources · src.path.8
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/include/pg_config_manual.h",
  "position": 9,
  "sha256": "3b513dda5408337ef7c31bca491844650b4ea2cdb1b688d6b99ab74ba3f06700",
  "source_id": "src.path.8",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/include/pg_config_manual.h#L63"
}
sources · src.path.9
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/include/statistics/statistics.h",
  "position": 10,
  "sha256": "6106a336fc725ca5a984e78b1c2e54aa5ee7aed130f3b005bebff35c07eadc5b",
  "source_id": "src.path.9",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/include/statistics/statistics.h#L19"
}

Source references

Full definition and evidence JSON

Definition sources

center · PostgreSQL 18 · english-manuals:c8e7103ac5c9a024d656b56359ff9d4eec2ebb5b7809b68e4b75851ca59e64e5

Text language: en · english-manuals:c8e7103ac5c9a024d656b56359ff9d4eec2ebb5b7809b68e4b75851ca59e64e5