How to fix Cache lookup failed for type in PostgreSQL

PostgreSQLADVANCEDHIGHUpdated Dec 29, 2025ยท 256 views

The "Cache lookup failed for type" error occurs when PostgreSQL cannot find a data type with a specific OID (Object Identifier) in its internal system catalog cache. This typically happens after types or schemas have been dropped and recreated while connections remain active. The cache mismatch causes queries and functions to fail until connections are reset or the application is restarted.

Quick fix

Fixes XX000

# For web applications
sudo systemctl restart myapp
# or
kill $(pgrep -f "node.*app.js")
npm start

# For .NET applications
sudo systemctl restart dotnetapp
# or
iisreset
  1. Immediately restart the application
  2. Clear connection pools if using application frameworks
  3. Review recent schema migrations for type changes
  4. Perform a database backup and restore if errors persist
postgresql โ€” error
# For web applications
sudo systemctl restart myapp
# or
kill $(pgrep -f "node.*app.js")
npm start
# For .NET applications
sudo systemctl restart dotnetapp
# or
iisreset
Cache lookup failed for type

What this error means

PostgreSQL maintains an internal cache of data types mapped by their OID (Object ID). When a cached reference points to a type that no longer exists or has been recreated with a different OID, PostgreSQL throws error XX000: "Cache lookup failed for type". This is an internal catalog integrity issue. The error commonly occurs in three scenarios: (1) A type or schema was dropped and recreated while the application was running, leaving stale cache entries; (2) A database migration changed type definitions without properly invalidating cached connections; (3) A function references a type that was deleted after the function was compiled into the cache. Unlike syntax or constraint errors, this is a connection-level caching issue that persists across queries until the connection's cache is cleared.

Typical symptoms

  • Functions fail intermittently with "cache lookup failed for type NNN" where NNN is a numeric OID
  • Errors occur immediately after running database migrations that drop/recreate types or schemas
  • Application throws cache lookup errors until restart
  • Errors happen inconsistently: some connections work while others fail
  • Website/application works fine until a schema migration is deployed
  • Backup/restore operations (pg_dump) fail with this error
  • Npgsql/.NET applications throw "XX000: cache lookup failed for type 0"

Common causes

  1. A type or enum was dropped and then recreated with the same name, but the OID changed. Existing connections cached the old OID and cannot find it.
  2. A schema was dropped and recreated during active database connections, leaving stale type references in cached function definitions.
  3. Database migrations executed while the application was running, causing in-flight requests to reference types that no longer exist.
  4. A function uses a type as a parameter or return type, and that type was deleted. The compiled function still references the old OID.
  5. Connection pooling maintains stale connections across schema changes, causing new queries to use outdated type metadata.
  6. PostgreSQL version upgrade where internal type OIDs changed, but application drivers cached old mappings.

How to fix "Cache lookup failed for type"

1Immediately restart the application

The fastest resolution is to restart your application to clear all cached connections and type metadata:

bash
# For web applications
sudo systemctl restart myapp
# or
kill $(pgrep -f "node.*app.js")
npm start

# For .NET applications
sudo systemctl restart dotnetapp
# or
iisreset

This forces all connections to reconnect and rebuild their type cache from the current database schema.

2Clear connection pools if using application frameworks

If restarting is not possible, clear the database connection pool:

For Node.js with pg or Sequelize:

javascript
const pool = new pg.Pool();
await pool.end(); // Drain all connections
const newPool = new pg.Pool(); // Create fresh connections

For .NET with Npgsql:

csharp
using var conn = new NpgsqlConnection(connectionString);
conn.Open();
conn.ReloadTypes(); // Refresh type cache
conn.Close();
// Clear the connection pool
NpgsqlConnection.ClearAllPools();

For Python with psycopg2:

python
conn.close()
psycopg2.extensions.connection.isolation_level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT
conn = psycopg2.connect(dsn)
3Review recent schema migrations for type changes

Examine your migration logs to identify what types or schemas were modified:

sql
SELECT version, description, installed_on FROM schema_migrations ORDER BY version DESC LIMIT 10;

Look for migrations that:
- Dropped and recreated custom types or enums
- Modified type definitions without safe migrations
- Dropped and recreated schemas containing user types

For example, this pattern is dangerous:

sql
-- Migration 001: Create enum
CREATE TYPE status_enum AS ENUM ('active', 'inactive');

-- Migration 002: Unsafe - creates a new OID
DROP TYPE status_enum;
CREATE TYPE status_enum AS ENUM ('active', 'inactive', 'pending');

Safer approach:

sql
-- Instead of dropping, add the value
ALTER TYPE status_enum ADD VALUE 'pending';
4Perform a database backup and restore if errors persist

If the problem continues after restarting, the database catalog may be corrupted. Perform a clean backup and restore:

bash
# On the source server
pg_dumpall > backup.sql

# Stop PostgreSQL
sudo systemctl stop postgresql

# Remove corrupted data directory
sudo rm -rf /var/lib/postgresql/15/main

# Reinitialize the database cluster
sudo -u postgres /usr/lib/postgresql/15/bin/initdb -D /var/lib/postgresql/15/main

# Start PostgreSQL
sudo systemctl start postgresql

# Restore from backup
psql -f backup.sql

Note: This is a last resort. Make sure you have verified backups before attempting this.

5Verify PostgreSQL version compatibility

If you recently upgraded PostgreSQL, check for version-specific type OID changes:

bash
psql --version
psql -U postgres -c "SELECT version();"  # Check server version

If upgrading (e.g., from PostgreSQL 12 to 15), always follow the official upgrade procedure:

bash
# Use pg_upgrade for a faster upgrade
pg_upgrade --old-datadir /var/lib/postgresql/12/main --new-datadir /var/lib/postgresql/15/main

Do not simply restore a dump from an older version and expect it to work perfectly.

Advanced notes

Deep Dive: Type OID Mapping and Caching: PostgreSQL internally identifies every data type by a 32-bit integer OID. When a client connects, the driver (psycopg2, Npgsql, pg, etc.) caches OID-to-type mappings. If a type is dropped and recreated, PostgreSQL assigns a new OID, but cached connections still reference the old one. This mismatch causes the "cache lookup failed" error. In Npgsql specifically, you can call conn.ReloadTypes() to force a refresh, but the underlying issue is the stale OID. For critical systems, use proper migration tools (Flyway, Liquibase, Alembic) that handle type changes safely. When modifying enums, use ALTER TYPE...ADD VALUE instead of DROP/CREATE. For other types, create a new type with a different name, migrate data, then drop the old one. Connection pools must be drained between schema changes in production environments. Monitor your migration logs and test schema changes thoroughly in staging before deploying to production.

Frequently asked questions

What does "XX000" mean?
PostgreSQL maintains an internal cache of data types mapped by their OID (Object ID). When a cached reference points to a type that no longer exists or has been recreated with a different OID, PostgreSQL throws error XX000: "Cache lookup failed for type". This is an internal catalog integrity issue.
How do I fix "XX000"?
The "Cache lookup failed for type" error occurs when PostgreSQL cannot find a data type with a specific OID (Object Identifier) in its internal system catalog cache. This typically happens after types or schemas have been dropped and recreated while connections remain active. The cache mismatch causes queries and functions to fail until connections are reset or the application is restarted.
What causes "XX000"?
A type or enum was dropped and then recreated with the same name, but the OID changed. Existing connections cached the old OID and cannot find it. A schema was dropped and recreated during active database connections, leaving stale type references in cached function definitions. Database migrations executed while the application was running, causing in-flight requests to reference types that no longer exist.
Is the "XX000" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading