BUG #19634: Hash partition with large MODULUS causes "invalid memory alloc request size"
Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.
You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:
docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253506psql -h localhost -U postgresBuilt from patchset v2 (message #2), August 23, 2026 at 12:22 PM.
Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:
git clone --branch t253506_2 https://github.com/hackorum-dev/postgres.gitIn a checkout you already have, add the fork once:
git remote add hackorum https://github.com/hackorum-dev/postgres.gitthen, for this patchset and every later one:
git fetch hackorum t253506_2 && git checkout t253506_2Patchset v2 (message #2) is on t253506_2
The following bug has been logged on the website:
Bug reference: 19634
Logged by: Zheng Hacker
Email address: hackerzheng666@gmail.com
PostgreSQL version: 19beta3
Operating system: Linux x86_64
Description:
Creating a hash partition with MODULUS >= 268435457 causes an internal error
"invalid memory alloc request size" on any subsequent query against the
partitioned table. The table becomes permanently unusable — SELECT,
INSERT,
and all other operations fail with the same error. Only DROP TABLE works.
Minimal reproducer (tested on PG 20devel commit 609f969, 2026-08-21):
CREATE TABLE t (id int) PARTITION BY HASH (id);
CREATE TABLE t_p0 PARTITION OF t FOR VALUES WITH (MODULUS 268435457,
REMAINDER 0);
SELECT * FROM t; -- ERROR: invalid memory alloc request size 1073741828
Root cause:
In src/backend/partitioning/partbounds.c, create_hash_bounds() (line 390)
allocates an array indexed by greatest_modulus:
boundinfo->nindexes = greatest_modulus;
boundinfo->indexes = palloc_array(int, greatest_modulus);
When greatest_modulus >= 268435457, this requests 268435457 * 4 =
1073741828
bytes, exceeding MaxAllocSize (1073741823 = 1GB - 1). No bounds check
exists
on the modulus value before this allocation.
The validation in check_new_partition_bound() (line ~2927) runs AFTER
create_hash_bounds() is called during partition descriptor loading, so it
never gets a chance to reject the invalid modulus.
Impact:
- Affects all versions since hash partitioning was introduced (PG 11+)
- The partition is created successfully (CREATE TABLE succeeds)
- But any access to the parent table fails permanently
- Only DROP TABLE recovers the table
- Any unprivileged user with CREATE TABLE permission can trigger this
Suggested fix:
Add a bounds check in create_hash_bounds() before the allocation, or
validate modulus against MaxAllocSize in check_new_partition_bound()
before partition descriptor loading.
PostgreSQL version: 20devel (commit 609f969)
OS: Ubuntu 22.04 x86_64
Hello,
I propose following patch that adds the check to new_partition_bound
routine:
postgres=# CREATE TABLE t (id int) PARTITION BY HASH (id);
CREATE TABLE
postgres=# CREATE TABLE t_p0 PARTITION OF t FOR VALUES WITH (MODULUS
268435457,
REMAINDER 0);
ERROR: hash partitions bounds are too large
DETAIL: Creating hash partitions for modulus 268435457 would require
too much memory.
HINT: Reduce the number of partitions.
postgres=#
Regards,
Pierre Forstmann
Le 21/08/2026 à 05:44, PG Bug reporting form a écrit :
Show quoted text
The following bug has been logged on the website:
Bug reference: 19634
Logged by: Zheng Hacker
Email address: hackerzheng666@gmail.com
PostgreSQL version: 19beta3
Operating system: Linux x86_64
Description:Creating a hash partition with MODULUS >= 268435457 causes an internal error
"invalid memory alloc request size" on any subsequent query against the
partitioned table. The table becomes permanently unusable — SELECT,
INSERT,
and all other operations fail with the same error. Only DROP TABLE works.Minimal reproducer (tested on PG 20devel commit 609f969, 2026-08-21):
CREATE TABLE t (id int) PARTITION BY HASH (id);
CREATE TABLE t_p0 PARTITION OF t FOR VALUES WITH (MODULUS 268435457,
REMAINDER 0);
SELECT * FROM t; -- ERROR: invalid memory alloc request size 1073741828Root cause:
In src/backend/partitioning/partbounds.c, create_hash_bounds() (line 390)
allocates an array indexed by greatest_modulus:boundinfo->nindexes = greatest_modulus;
boundinfo->indexes = palloc_array(int, greatest_modulus);When greatest_modulus >= 268435457, this requests 268435457 * 4 =
1073741828
bytes, exceeding MaxAllocSize (1073741823 = 1GB - 1). No bounds check
exists
on the modulus value before this allocation.The validation in check_new_partition_bound() (line ~2927) runs AFTER
create_hash_bounds() is called during partition descriptor loading, so it
never gets a chance to reject the invalid modulus.Impact:
- Affects all versions since hash partitioning was introduced (PG 11+)
- The partition is created successfully (CREATE TABLE succeeds)
- But any access to the parent table fails permanently
- Only DROP TABLE recovers the table
- Any unprivileged user with CREATE TABLE permission can trigger thisSuggested fix:
Add a bounds check in create_hash_bounds() before the allocation, or
validate modulus against MaxAllocSize in check_new_partition_bound()
before partition descriptor loading.PostgreSQL version: 20devel (commit 609f969)
OS: Ubuntu 22.04 x86_64
Hi,
On 2026-08-21 14:04:09 +0200, Pierre Forstmann wrote:
I propose following patch that adds the check to new_partition_bound
routine:postgres=# CREATE TABLE t (id int) PARTITION BY HASH (id);
CREATE TABLE
postgres=# CREATE TABLE t_p0 PARTITION OF t FOR VALUES WITH (MODULUS
268435457,
REMAINDER 0);
ERROR: hash partitions bounds are too large
DETAIL: Creating hash partitions for modulus 268435457 would require too
much memory.
HINT: Reduce the number of partitions.
postgres=#
I am not sure it's worth doing *anything* here. There's at most a slightly
suboptimal error message here. There are many many ways to get those. Nobody
sane would create a setup like this unless they're explicitly trying to find
unexpected errors or such.
Greetings,
Andres Freund