SOLUTION: n8n “Workflow not found” Error - Corrupted PostgreSQL Index
========================================
PROBLEM
Workflows periodically disappeared from n8n UI showing “Workflow not found” error, even though they existed in PostgreSQL database. Restarting n8n temporarily fixed it, but problem returned daily.
========================================
ROOT CAUSE
CORRUPTED B-TREE INDEX on workflow_entity.id column. The index returned 0 rows while actual data existed in the table.
========================================
DIAGNOSIS
Key test that revealed the issue:
SQL with index (BROKEN - returned 0 rows):
SELECT id, name FROM workflow_entity WHERE id = ‘your-workflow-id’;
SQL without index (WORKED - returned 1 row):
SET enable_indexscan = OFF;
SET enable_bitmapscan = OFF;
SELECT id, name FROM workflow_entity WHERE id = ‘your-workflow-id’;
RESET enable_indexscan;
RESET enable_bitmapscan;
Result: Sequential scan found data, but index scan didn’t = CORRUPTED INDEX
Additional findings:
- Two duplicate indexes on same id column (workflow_entity_pkey and pk_workflow_entity_id)
- High update frequency: 3,360 updates vs 88 inserts (38:1 ratio)
- Index actively used: 422,716 scans on corrupted index
========================================
IMMEDIATE FIX
Step 1: Rebuild indexes
REINDEX TABLE workflow_entity;
REINDEX TABLE shared_workflow;
Step 2: Restart n8n
docker restart n8n-container-name
Step 3: Verify fix
SELECT id, name FROM workflow_entity WHERE id = 'your-workflow-id';
(should now return 1 row)
========================================
LONG-TERM PREVENTION
Create automated nightly REINDEX via cron:
-
Create script /root/n8n-reindex.sh:
#!/bin/bash
LOG_FILE=“/var/log/n8n-reindex.log”
echo “[$(date ‘+%Y-%m-%d %H:%M:%S’)] Starting REINDEX…” >> $LOG_FILE
docker exec -i postgres-container-name psql -U postgres-user -d n8n -c “REINDEX TABLE workflow_entity;” >> $LOG_FILE 2>&1
docker exec -i postgres-container-name psql -U postgres-user -d n8n -c “REINDEX TABLE shared_workflow;” >> $LOG_FILE 2>&1
echo “[$(date ‘+%Y-%m-%d %H:%M:%S’)] REINDEX completed” >> $LOG_FILE
-
Make executable:
chmod +x /root/n8n-reindex.sh
-
Add to crontab (runs daily at 3:00 AM UTC):
crontab -e
0 3 * * * /root/n8n-reindex.sh
========================================
WHY IT HAPPENED
Corruption likely caused by:
- High update frequency (38 updates per insert)
- Duplicate indexes competing for same data
- Possible improper PostgreSQL shutdowns (Docker restarts)
- Disk I/O issues
========================================
HOW TO TEST IF YOU HAVE THIS ISSUE
Run this SQL to test for index corruption:
SET enable_indexscan = OFF;
SET enable_bitmapscan = OFF;
SELECT id, name FROM workflow_entity WHERE id = 'your-missing-workflow-id';
RESET enable_indexscan;
RESET enable_bitmapscan;
If this returns a row but normal SELECT doesn’t = YOU HAVE INDEX CORRUPTION
========================================
SYSTEM INFO
- n8n version: 1.120.4
- Database: PostgreSQL 16.11
- Deployment: Docker Compose
- OS: Ubuntu 24.04.2 LTS
========================================
KEY TAKEAWAYS
- Index corruption can be SILENT - data exists but queries return empty
- Sequential scans bypass corrupted indexes (useful for diagnosis)
- Regular REINDEX prevents corruption accumulation
- High update frequency stresses indexes more than inserts
- Duplicate indexes can cause conflicts under heavy load
Hope this helps others with similar issues!