How to fix Transaction resolution unknown in PostgreSQL
This error occurs when PostgreSQL cannot determine whether a transaction was committed or rolled back due to a connection loss. It typically indicates a network disruption between your application and the database server.
Quick fix
Fixes 08007
grep "transaction resolution unknown" /var/log/postgresql/postgresql.log- Check PostgreSQL server logs immediately
- Verify data consistency in the database
- Check for idle transactions and locks
- Implement automatic retry logic with exponential backoff
grep "transaction resolution unknown" /var/log/postgresql/postgresql.logTransaction resolution unknown
What this error means
The "Transaction resolution unknown" error (SQLSTATE 08007) belongs to PostgreSQL's Connection Exception class and signifies that the outcome of a transaction is indeterminate. This happens when the connection between your client application and the PostgreSQL server is severed before the database can report the final state of the transaction. The transaction may have been committed, rolled back, or left in an incomplete state, and your application cannot determine which. This is a critical error because it leaves your data in an uncertain state and requires explicit recovery actions.
Typical symptoms
- Connection drops or timeouts during transaction commit/rollback
- Application receives "Connection lost" or "Connection reset" errors
- Data appears inconsistent between what application expects and what is actually in the database
- Network interruptions coincide with transaction failures
- ORM or database driver reports transaction state as unknown after network failure
Common causes
- Network connectivity loss between application and PostgreSQL server during transaction completion
- Database server crashed or was forcefully restarted mid-transaction
- Firewall or network infrastructure dropping idle connections during long transactions
- Client application crashed after issuing COMMIT but before receiving confirmation
- Connection pool timeout exceeded before transaction could complete
- Virtual machine or container migration without graceful connection handling
How to fix "Transaction resolution unknown"
Look at the PostgreSQL server logs to see if the transaction was actually committed or rolled back:
grep "transaction resolution unknown" /var/log/postgresql/postgresql.logOr in the PostgreSQL data directory:
tail -f /usr/local/var/postgres/server.logCheck the timestamp when the error occurred and look for COMMIT/ROLLBACK entries in that timeframe.
Query the database directly to check if your transaction was actually applied:
SELECT * FROM your_table WHERE id = your_transaction_id;If the data is present, the transaction committed despite the client error. If absent, it was rolled back. This tells you the actual state of your database and what recovery steps you need.
Orphaned transactions may still hold locks on tables. Find them with:
SELECT pid, usename, state, query
FROM pg_stat_activity
WHERE state = 'idle in transaction';If you find processes in "idle in transaction" state, terminate them:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle in transaction' AND pid <> pg_backend_pid();This prevents locks from blocking other operations.
Update your application to retry failed transactions with exponential backoff:
async function executeTransactionWithRetry(
query: string,
maxRetries: number = 3
): Promise<any> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const result = await client.query(query);
return result;
} catch (error) {
if (error.code === '08007' && attempt < maxRetries) {
// Exponential backoff: 100ms, 200ms, 400ms
const delayMs = 100 * Math.pow(2, attempt - 1);
await new Promise(resolve => setTimeout(resolve, delayMs));
continue;
}
throw error;
}
}
}This gives transient network issues a chance to recover.
Configure your connection pool to handle disconnections gracefully:
// Using node-postgres with connection pool
const pool = new Pool({
connectionTimeoutMillis: 2000,
idleTimeoutMillis: 30000,
max: 20,
});
// For Prisma
prisma = new PrismaClient({
datasources: {
db: {
url: process.env.DATABASE_URL + "?connect_timeout=10",
},
},
});Proper timeout settings prevent connections from staying open indefinitely after a network issue.
Monitor for connection failures and set up alerts:
-- Run this periodically to check for problematic patterns
SELECT
datname,
count(*) as connection_count,
state
FROM pg_stat_activity
GROUP BY datname, state
ORDER BY connection_count DESC;Set up application-level logging to capture when error code 08007 occurs, including:
- Exact timestamp
- Transaction details
- Network conditions at the time
- Whether the transaction actually succeeded
This helps you identify patterns and root causes.
Advanced notes
Error 08007 is particularly tricky because your application must handle two simultaneous uncertainties: the network failure itself AND the unknown transaction state. Modern connection pools and ORMs like Prisma handle some of this automatically, but you should still implement explicit recovery. For critical operations, consider using application-level idempotency keys so you can safely replay failed transactions without duplicating data. PostgreSQL does not support two-phase commit at the protocol level for client applications, so infrastructure-level solutions (connection pooling, circuit breakers, or service meshes) provide the best protection. When using transactions with savepoints, error 08007 will abort the entire transaction; you cannot recover just the savepoint without knowing the full transaction state.
Frequently asked questions
- What does "08007" mean?
- The "Transaction resolution unknown" error (SQLSTATE 08007) belongs to PostgreSQL's Connection Exception class and signifies that the outcome of a transaction is indeterminate. This happens when the connection between your client application and the PostgreSQL server is severed before the database can report the final state of the transaction. The transaction may have been committed, rolled back, or left in an incomplete state, and your application cannot determine which.
- How do I fix "08007"?
- This error occurs when PostgreSQL cannot determine whether a transaction was committed or rolled back due to a connection loss. It typically indicates a network disruption between your application and the database server.
- What causes "08007"?
- Network connectivity loss between application and PostgreSQL server during transaction completion Database server crashed or was forcefully restarted mid-transaction Firewall or network infrastructure dropping idle connections during long transactions
- Is the "08007" 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
- ๐PostgreSQL Official Documentation
- ๐PostgreSQL Error Codes - Class 08 Connection Exception(Official Docs)
- ๐PostgreSQL - Serialization Failure Handling(Official Docs)
- ๐PostgreSQL Tutorial - Transactions(Official Docs)