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.
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.
First, determine which enum type was altered and which transaction is causing the 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%';Look for transactions that started before your ALTER TYPE command.
If possible, gracefully commit or terminate the transactions using the old enum definition:
-- 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.
When adding enum values, use the SAFE option to allow immediate use in existing transactions:
-- 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.
After altering enums, restart your application or refresh connection pools:
# 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 operationThis ensures all connections have the updated enum definition.
Coordinate enum changes with application deployments:
-- 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.
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.
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL