How to fix Could not open relation with OID in PostgreSQL

PostgreSQLADVANCEDCRITICALUpdated Dec 29, 2025· 228 views

PostgreSQL cannot find a table or index by its internal Object ID (OID), usually due to dropped tables, replication issues, or system catalog corruption. This critical error indicates missing or inconsistent database objects that require investigation and repair.

Quick fix

Fixes Could not open relation with OID

ERROR: could not open relation with OID 16391
  1. Identify the affected OID from the error message
  2. Check if the OID exists in the system catalog
  3. Clear the relation cache to remove stale references
  4. For replication issues, check and resync if needed
postgresql — error
ERROR: could not open relation with OID 16391
Could not open relation with OID

What this error means

The "could not open relation with OID" error occurs when PostgreSQL attempts to access a table or index using its internal Object Identifier (OID) but cannot find it in the system catalog. This indicates a mismatch between cached OID references and actual database objects. The error is serious because it suggests either a table was dropped while other operations were still referencing it, system catalog corruption, replication inconsistency, or concurrent operations that removed objects during critical moments. PostgreSQL maintains OIDs for all relations (tables, indexes, views), and this error signals that the expected object no longer exists or is inaccessible.

Typical symptoms

  • Query execution fails with "ERROR: could not open relation with OID [number]"
  • Error occurs intermittently after replication setup or pg_repack operations
  • Reindex operations fail with this error
  • pg_class queries for the reported OID return no results
  • Error appears in monitoring queries that scan table sizes and system information
  • Issue may be transient and resolve after retrying the query

Common causes

  1. Temporary table or dropped table referenced in cached query plan or stale relation cache
  2. pg_repack operations on primary database with streaming replication enabled causing index references to become invalid
  3. Concurrent reindex and drop operations on the same index without proper locking between checks and execution
  4. System catalog corruption where pg_index or pg_depend contains references to non-existent OIDs
  5. Replication lag where a table was dropped on primary but secondary still has references in memory
  6. Stale relation cache that retains OID references to objects that no longer exist
  7. Querying TOAST relations or system tables without proper filtering in disk usage monitoring queries

How to fix "Could not open relation with OID"

1Identify the affected OID from the error message

The error will include a specific OID number. Note this number:

bash
ERROR: could not open relation with OID 16391

You will need this OID to investigate what object it refers to.

2Check if the OID exists in the system catalog

Query the pg_class table to see if the OID still exists:

sql
SELECT oid, relname, reltype, relkind 
FROM pg_class 
WHERE oid = 16391;

If this returns no rows, the object has been dropped or the catalog is corrupted. If it returns rows, the object exists but is inaccessible through normal cache mechanisms.

3Clear the relation cache to remove stale references

If the OID no longer exists, you need to clear cached references. For a quick fix, restart the PostgreSQL server (if possible) to flush all in-memory caches:

bash
sudo systemctl restart postgresql
# or
sudo service postgresql restart

Alternatively, if you cannot restart, disconnect all clients and try again:

sql
-- List current connections
SELECT pid, usename, application_name, state FROM pg_stat_activity 
WHERE pid <> pg_backend_pid();

-- Terminate non-critical connections
SELECT pg_terminate_backend(pid) FROM pg_stat_activity 
WHERE pid <> pg_backend_pid() AND state = 'idle';
4For replication issues, check and resync if needed

If this error occurs in a replication setup, verify replication status:

sql
-- Check replication status on primary
SELECT slot_name, slot_type, active, confirmed_flush_lsn 
FROM pg_replication_slots;

-- View replication lag
SELECT client_addr, client_hostname, usename, application_name, 
       pg_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS bytes_behind 
FROM pg_stat_replication;

If replication is significantly lagged or inconsistent, consider:
1. Pausing any pg_repack operations on the primary
2. Allowing the secondary to catch up
3. Taking a fresh base backup and reinitializing the replica

5Rearrange queries to use table names instead of OIDs

For monitoring and system queries, avoid relying on cached OIDs. Use table and schema names directly:

sql
-- Problematic: may fail with OID errors
SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(oid)) 
FROM pg_tables 
LEFT JOIN pg_class ON relname = tablename;

-- Better: uses names directly, adds TOAST filter
SELECT schemaname, tablename, 
       pg_size_pretty(pg_total_relation_size(to_regclass(schemaname||"."||tablename)))
FROM pg_tables 
WHERE schemaname NOT IN ("pg_catalog", "information_schema");

-- For disk usage without TOAST issues
SELECT schemaname, tablename 
FROM pg_tables 
WHERE schemaname NOT IN ("pg_catalog", "information_schema") 
AND oid NOT IN (SELECT reltoastrelid FROM pg_class WHERE reltoastrelid != 0);
6Check system catalog integrity for corruption

If the OID still exists but remains inaccessible, check for catalog corruption:

sql
-- Look for orphaned references in pg_index
SELECT indexrelid, indrelid FROM pg_index 
WHERE indexrelid = 16391 AND indexrelid NOT IN (SELECT oid FROM pg_class);

-- Check pg_depend for broken references
SELECT objid, deptype FROM pg_depend 
WHERE objid = 16391 AND objid NOT IN (SELECT oid FROM pg_class);

If corruption is found, you may need to restore from backup or use emergency recovery options (running with -P flag to ignore system indexes).

7If error is transient, retry the failed query

In many cases, this error is transient and disappears after a retry, especially if the query succeeded once before.

sql
-- If your query fails with OID error, simply retry
RETRY QUERY; -- Your original query

If retrying consistently succeeds, the issue was likely a stale cache that has since been cleared. Monitor for recurrence.

Advanced notes

For system administration, understand that PostgreSQL maintains an in-memory relation cache (relcache) to speed up object lookups. Under concurrent operations (especially pg_repack with replication), this cache can become inconsistent with the actual catalog. The -P (skip system indexes) flag is an emergency recovery option that can be used when starting the backend individually for maintenance—it forces PostgreSQL to ignore system indexes and scan system tables sequentially, bypassing cached OID references. This is extremely slow but may allow recovery from severe catalog corruption. Additionally, when using pg_repack in production with streaming replication, ensure reindex operations on the primary complete and fully replicate to secondaries before issuing concurrent DDL operations. Finally, monitoring queries should always use pg_total_relation_size() with the relation name via to_regclass() rather than assuming OIDs remain valid—this is more robust and prevents cascading cache inconsistency issues.

Frequently asked questions

What does "Could not open relation with OID" mean?
The "could not open relation with OID" error occurs when PostgreSQL attempts to access a table or index using its internal Object Identifier (OID) but cannot find it in the system catalog. This indicates a mismatch between cached OID references and actual database objects. The error is serious because it suggests either a table was dropped while other operations were still referencing it, system catalog corruption, replication inconsistency, or concurrent operations that removed objects during critical moments.
How do I fix "Could not open relation with OID"?
PostgreSQL cannot find a table or index by its internal Object ID (OID), usually due to dropped tables, replication issues, or system catalog corruption. This critical error indicates missing or inconsistent database objects that require investigation and repair.
What causes "Could not open relation with OID"?
Temporary table or dropped table referenced in cached query plan or stale relation cache pg_repack operations on primary database with streaming replication enabled causing index references to become invalid Concurrent reindex and drop operations on the same index without proper locking between checks and execution
Is the "Could not open relation with OID" error serious?
Yes. This is a critical-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading