Fix ERROR_RXACT_INVALID_STATE (0x00000559) in Registry Transactions
Error 0x00000559 means a registry transaction is in the wrong state. This usually happens when you try to commit or rollback after the transaction has already finished.
What Triggers Error 0x00000559
I've seen this error pop up in two main scenarios. First, when a developer or script tries to commit a registry transaction that's already been committed or rolled back. Second, when an application crashes mid-transaction and leaves the handle dangling. The error code ERROR_RXACT_INVALID_STATE literally means the transaction's state—active, prepared, committed, rolled back—doesn't match what the code expects.
For example, you might see this in event logs after a failed Windows Update, or if you're using the RegCommitTransaction API and the transaction handle has already been closed. Common on Windows 10 versions 1809 through 22H2, and yes, it still bites on Windows 11.
Cause #1: Double Commit or Rollback on a Transaction
This is the most common trigger. A script calls RegCommitTransaction or RegRollbackTransaction twice on the same handle. The first call succeeds. The second call hits 0x00000559 because the transaction is no longer active.
The Fix: Trace and Fix Your Transaction Flow
- Check your code: Are you calling
RegCommitTransactionmore than once? If so, the second call will always fail with this error. Wrap it in a conditional: - Use a state flag: Set a boolean like
transactionCommitted = trueafter the first commit, and check it before any subsequent commit or rollback calls. - Close handles properly: After committing or rolling back, call
RegCloseKeyon the transaction handle. This avoids accidentally reusing it. But remember—closing the handle doesn't roll back an uncommitted transaction. You must explicitly callRegRollbackTransactionfirst.
HANDLE hTransaction = RegCreateTransaction(...);
if (RegCommitTransaction(hTransaction) == ERROR_SUCCESS) {
// Transaction committed. Do NOT call RegCommitTransaction again.
// Close the handle with RegCloseKey(hTransaction) instead.
}
If you're not writing code but seeing this in logs from a third-party app, skip to Cause #2. That's your problem.
Cause #2: Transaction Timeout or Abandonment
Registry transactions in Windows have a built-in timeout. If your write operations take too long—say, you're writing a ton of values across subkeys—the transaction auto-rolls back. Any subsequent attempt to commit or write to that handle triggers 0x00000559.
I've seen this happen with registry cleaner tools and Windows Update servicing stacks on older builds. The transaction times out after 60 seconds by default, and then the application tries to commit a zombie.
The Fix: Increase Timeout or Break It Up
- Increase the transaction timeout: When calling
RegCreateTransaction, pass a largerdwOptionsvalue for the timeout. The default is 60 seconds, but you can set it higher: - Break writes into smaller chunks: Instead of writing 2000 values in one transaction, batch them in groups of 500. This keeps each transaction under the timeout.
- Use a longer timeout for servicing operations: If you're building a tool for Windows Update or driver deployment, set the timeout to 300 seconds (5 minutes). That covers most real-world scenarios.
REG_TXN_TRANSACTION_TIME timeout = {0};
timeout.Multiple = 120; // 120 seconds
timeout.Unit = REG_TXN_UNIT_SECONDS;
HANDLE hTrans = RegCreateTransaction(REG_TXN_CREATE_NONE, &timeout);
Cause #3: Orphaned Transaction Handle After a Crash
This one's trickier. An application crashes while a registry transaction is active. The handle stays open in the kernel, but the user-mode process is gone. When the system tries to clean up—or when another instance of the app starts—it finds a transaction in an invalid state. The error surfaces in event logs or as a crash in the new process.
The Fix: Identify and Kill Orphaned Transactions
- Find the transaction handle: Use Process Explorer (from Sysinternals) or the
handle.exetool. Look for handles of typeTransactionowned by your application's PID. If the PID is stale, the handle is orphaned. - Restart the Kernel Transaction Manager (KTM): This is nuclear but works. Run in an elevated PowerShell:
- Use the ResMon tool: Resource Monitor can show handle leaks. Open ResMon, go to the Handle tab, and search for
Transaction. You can close individual handles if you know the PID. But honestly, restarting KTM is faster and safer.
Stop-Service -Name KtmRm -Force
Start-Service -Name KtmRm
This clears all orphaned transactions. Warning: Any in-flight transactions across the system will fail. Do this only when the specific app isn't critical.
If the error keeps recurring after a cleanup, the app has a bug. Contact the vendor and point them to the ERROR_RXACT_INVALID_STATE event. They need to fix their transaction lifecycle.
Quick-Reference Summary
| Cause | Fix | Difficulty |
|---|---|---|
| Double commit or rollback | Add a state flag; don't call commit/rollback twice | Intermediate |
| Transaction timeout | Increase timeout or batch writes | Intermediate |
| Orphaned handle after crash | Restart KTM service or use handle tools | Advanced |
No matter which cause is yours, the golden rule is: one commit or one rollback per transaction handle, then close it. Break that rule, and 0x00000559 will haunt you.
Was this solution helpful?