How to fix 55P04: unsafe_new_enum_value_usage in PostgreSQL

PostgreSQLINTERMEDIATEMEDIUMUpdated Dec 22, 2025ยท 115 views

SQLSTATE 55P04 occurs when PostgreSQL detects unsafe usage of a newly added enum value in a transaction that started before the enum was altered. This prevents data corruption by ensuring transactions see consistent enum definitions.

Quick fix

Fixes 55P04: unsafe_new_enum_value_usage

-- Check for recent enum alterations
SELECT schemaname, typname, nspname, obj_description(oid, 'pg_type')
FROM pg_type t
JOIN pg_namespace n ON t.typnamespace = n.oid
WHERE t.typtype = 'e'
AND t.typname LIKE '%your_enum%';

-- Find active transactions that might be using old enum definitions
SELECT pid, usename, application_name, client_addr, backend_start, query_start, state, query
FROM pg_stat_activity
WHERE state = 'active'
AND query LIKE '%your_enum%';
  1. Identify the affected transaction and enum
  2. Terminate or commit the problematic transactions
  3. Use the safe enum alteration method
  4. Restart or refresh application connections
postgresql โ€” error
-- Check for recent enum alterations
SELECT schemaname, typname, nspname, obj_description(oid, 'pg_type')
FROM pg_type t
JOIN pg_namespace n ON t.typnamespace = n.oid
WHERE t.typtype = 'e'
AND t.typname LIKE '%your_enum%';
-- Find active transactions that might be using old enum definitions
SELECT pid, usename, application_name, client_addr, backend_start, query_start, state, query
FROM pg_stat_activity
WHERE state = 'active'
AND query LIKE '%your_enum%';
55P04: unsafe_new_enum_value_usage

What this error means

SQLSTATE 55P04 belongs to PostgreSQL's custom error class 55 (object state error) and signals that a transaction is attempting to use a newly added enum value while still operating under the old enum definition. PostgreSQL enums are strongly typed, and when you add a new value with ALTER TYPE ... ADD VALUE, existing transactions that started before the ALTER TYPE cannot safely use the new value because they have cached the old enum definition. This prevents subtle bugs where different parts of the same transaction might see different enum definitions, which could lead to data corruption or inconsistent query results.

Typical symptoms

  • Transaction fails with error "55P04: unsafe_new_enum_value_usage" when trying to insert or update rows with a newly added enum value
  • Queries that reference the new enum value work in new sessions but fail in long-running transactions
  • Application logs show the error when performing DML operations after an enum alteration
  • Batch processing jobs or ETL pipelines that started before an enum change fail when they encounter the new value
  • Database migration scripts succeed but application code fails with this error in existing connections

Common causes

  1. Adding a new enum value with ALTER TYPE ... ADD VALUE while transactions are active
  2. Long-running transactions that started before an enum alteration and attempt to use the new value
  3. Connection pooling where connections are reused and have cached old enum definitions
  4. Application code that caches enum definitions at startup and doesn't refresh them after database changes
  5. Using the new enum value in triggers, functions, or views that were compiled with the old enum definition

How to fix "55P04: unsafe_new_enum_value_usage"

1Identify the affected transaction and enum

First, determine which enum type was altered and which transaction is causing the error:

sql
-- Check for recent enum alterations
SELECT schemaname, typname, nspname, obj_description(oid, 'pg_type')
FROM pg_type t
JOIN pg_namespace n ON t.typnamespace = n.oid
WHERE t.typtype = 'e'
AND t.typname LIKE '%your_enum%';

-- Find active transactions that might be using old enum definitions
SELECT pid, usename, application_name, client_addr, backend_start, query_start, state, query
FROM pg_stat_activity
WHERE state = 'active'
AND query LIKE '%your_enum%';

Look for transactions that started before your ALTER TYPE command.

2Terminate or commit the problematic transactions

If possible, gracefully commit or terminate the transactions using the old enum definition:

sql
-- For read-only transactions, try to commit them
-- (if they haven't done any writes that need to be rolled back)

-- To terminate a specific transaction:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE pid = <problematic_pid>;

-- Or terminate all transactions using a specific enum:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE query LIKE '%your_enum%'
AND state = 'active'
AND pid <> pg_backend_pid();

Warning: Terminating transactions will roll back any uncommitted work.

3Use the safe enum alteration method

When adding enum values, use the SAFE option to allow immediate use in existing transactions:

sql
-- Unsafe (default) - new value cannot be used in existing transactions:
ALTER TYPE status_enum ADD VALUE 'pending_review';

-- Safe - new value can be used in existing transactions:
ALTER TYPE status_enum ADD VALUE 'pending_review' BEFORE 'approved';
-- or
ALTER TYPE status_enum ADD VALUE 'pending_review' AFTER 'submitted';

The SAFE option (specifying position with BEFORE/AFTER) allows the new value to be used immediately in all transactions.

4Restart or refresh application connections

After altering enums, restart your application or refresh connection pools:

bash
# For applications using connection pools:
# 1. Drain the pool (stop accepting new connections)
# 2. Wait for existing connections to complete
# 3. Restart the pool

# For PgBouncer or other connection poolers:
pgbouncer -R /etc/pgbouncer/pgbouncer.ini

# For application-level solutions, implement a connection refresh:
# - Catch the 55P04 error
# - Close and reopen the database connection
# - Retry the operation

This ensures all connections have the updated enum definition.

5Implement enum change coordination

Coordinate enum changes with application deployments:

sql
-- Deployment checklist for enum changes:
-- 1. Schedule during low-traffic periods
-- 2. Drain connection pools before alteration
-- 3. Use SAFE enum addition when possible
-- 4. Deploy application code that uses new enum value AFTER the alteration
-- 5. Monitor for 55P04 errors and have rollback plan

-- Example safe deployment script:
BEGIN;
-- Drain connections (application-specific)
-- Perform safe enum alteration
ALTER TYPE user_role ADD VALUE 'moderator' AFTER 'user';
-- Wait for all connections to refresh (application-specific)
-- Deploy new application version
COMMIT;

Always test enum changes in staging first.

Advanced notes

PostgreSQL's enum safety mechanism prevents "split-brain" scenarios where different parts of a transaction see different enum definitions. This is especially important for serializable transactions and applications with long-lived connections. Consider using CHECK constraints with text columns instead of enums if you need more flexible schema evolution. For zero-downtime deployments, use multiple application versions that can handle both old and new enum values during the transition period.

Frequently asked questions

What does "55P04: unsafe_new_enum_value_usage" mean?
SQLSTATE 55P04 belongs to PostgreSQL's custom error class 55 (object state error) and signals that a transaction is attempting to use a newly added enum value while still operating under the old enum definition. PostgreSQL enums are strongly typed, and when you add a new value with ALTER TYPE ... ADD VALUE, existing transactions that started before the ALTER TYPE cannot safely use the new value because they have cached the old enum definition.
How do I fix "55P04: unsafe_new_enum_value_usage"?
SQLSTATE 55P04 occurs when PostgreSQL detects unsafe usage of a newly added enum value in a transaction that started before the enum was altered. This prevents data corruption by ensuring transactions see consistent enum definitions.
What causes "55P04: unsafe_new_enum_value_usage"?
Adding a new enum value with ALTER TYPE ... ADD VALUE while transactions are active Long-running transactions that started before an enum alteration and attempt to use the new value Connection pooling where connections are reused and have cached old enum definitions
Is the "55P04: unsafe_new_enum_value_usage" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading