PostgreSQL index corruption causes queries to return incorrect results or fail. Rebuild the corrupted index using REINDEX to restore normal database operations.
An index in PostgreSQL has become inconsistent with the actual data in the table. This happens when the index structure is damaged due to hardware failures, software bugs, or system crashes. When PostgreSQL tries to use a corrupted index to find data, it returns incorrect results or encounters errors. The good news is that indexes are derived from table data, so the underlying data remains intact and can be rebuilt.
First, safely stop your application to prevent further writes. Then connect to your database and run a query using the suspected index to confirm the corruption:
SET enable_seqscan = off; -- Force index usage
SELECT * FROM your_table WHERE indexed_column = value;
SET enable_seqscan = on; -- ResetIf you get different results or errors, the index is likely corrupted.
Enable and run the amcheck extension to formally detect corruption:
CREATE EXTENSION IF NOT EXISTS amcheck;
SELECT bt_index_check('your_index_name'::regclass);If amcheck reports DUPLICATE or BACKWARDS entries, corruption is confirmed.
Create a full backup in case anything goes wrong:
pg_dump -U postgres database_name > backup.sqlStore this backup safely on another system.
For a single corrupted index (quickest, but locks writes):
REINDEX INDEX CONCURRENTLY your_index_name;The CONCURRENTLY option allows reads and writes during rebuilding (slower but no downtime). For all indexes on a table:
REINDEX TABLE CONCURRENTLY your_table_name;Wait for the command to complete. Progress may be slow depending on table size.
After REINDEX completes, verify normal operation:
SET enable_seqscan = off;
SELECT COUNT(*) FROM your_table WHERE indexed_column = value;
SET enable_seqscan = on;Run the same query again without forcing the index. Both should return the same count.
Once verification is complete, restart your application:
# For systemd services
sudo systemctl restart your-app
# Or for Docker containers
docker-compose restart webMonitor logs to ensure the application connects successfully.
For system catalog index corruption (preventing PostgreSQL startup), restart PostgreSQL with single-user mode and -P flag: postgres -P -D /var/lib/postgresql/data. Then run REINDEX DATABASE;. Increase maintenance_work_mem to 2% of total RAM during large reindexing operations for better performance. If duplicate data violates the index uniqueness constraint, remove duplicates before attempting REINDEX. Consider using pg_repack as an alternative if you need zero-downtime reindexing without CONCURRENTLY.
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL
ERROR 42501: must be owner of table
How to fix "must be owner of table" in PostgreSQL
trigger cannot change partition destination
How to fix "Trigger cannot change partition destination" in PostgreSQL
SSL error: certificate does not match host name
SSL error: certificate does not match host name in PostgreSQL
No SSL connection
No SSL connection to PostgreSQL