RPC_NT_INVALID_ES_ACTION (0XC0030059) - encoding handle fix
You hit this when an RPC call tries to read or write data after the serialization handle is already closed. Happens in older apps or custom RPC code.
You're in the middle of deploying an old line-of-business app, maybe a custom COM+ component or a legacy VB6 app that uses DCE RPC serialization. The app crashes with error 0XC0030059. The event log shows something like "RPC_NT_INVALID_ES_ACTION - Invalid operation on the encoding/decoding handle". This usually pops up when the app tries to serialize or deserialize data after the RPC handle is already freed or closed. I've seen it happen most often on Windows Server 2012 R2 and 2016 during app migration from older OS versions.
What causes this error?
The encoding or decoding handle in RPC is a one-shot thing. Once you call MesEncodeIncrementalHandleClose or MesDecodeIncrementalHandleClose, that handle is gone. If your code tries to call MesEncodeIncrementalHandleCreate again on the same handle, or tries to read/write data after calling close, you get 0XC0030059.
The root cause is almost always a bug in the client or server code that doesn't track the handle state properly. It's not a configuration issue, not a firewall problem, not a DNS glitch. It's a coding error. I've seen it in IDL-generated stubs that have hardcoded handle reuse, especially when porting from Windows XP-era code to newer Windows versions where the RPC runtime got stricter about handle lifecycle.
Step-by-step fix
- Identify the app using the handle. Check the event log for the PID of the crashing process. Use Task Manager to match PID to the app name. If it's a service, note the service name.
- Get the source code or contact the vendor. If you wrote the app, look for calls to
MesEncodeIncrementalHandleCreate,MesDecodeIncrementalHandleCreate, and their close counterparts. If it's third-party, open a ticket with them and give them the error code. This isn't something you can patch with a registry key. - Add handle state tracking. The fix is simple in concept: after calling close on the handle, set any pointer to that handle to NULL or invalid. Then check for NULL before any subsequent encode/decode call. Example in C++:
RPC_STATUS status; handle_t hEncode = NULL; status = MesEncodeIncrementalHandleCreate(NULL, ... , &hEncode); if (status != RPC_S_OK) { /* handle error */ } // ... use hEncode ... MesEncodeIncrementalHandleClose(&hEncode); hEncode = NULL; // critical — prevents reuse // later in code: if (hEncode != NULL) { // don't use it, it's dead } - Recompile the app. Rebuild the client and server with the fix. Test on a development environment first. The MIDL compiler's default stubs don't add this guard—you have to do it manually.
- If you can't change the code, isolate the app. Run the app on a separate Windows Server or container where it won't affect other services. Sometimes the error is intermittent; moving it to a dedicated VM reduces the blast radius.
Still failing? Check these
- Multiple threads sharing a handle. If two threads call close on the same handle, the second thread will trigger 0XC0030059. Add a mutex or critical section around handle operations.
- Memory corruption. A buffer overflow in the serialized data can corrupt the handle structure. Run the app with Application Verifier to catch heap corruption.
- Wrapper libraries. Some COM libraries wrap RPC handles internally. Check if the error originates from a DLL like ole32.dll or rpcrt4.dll. That points to a bug in the library's RPC usage, not your app.
- Windows version differences. On Windows Server 2019 and later, the RPC runtime detects handle misuse more aggressively. If the app worked on Server 2008 but not on Server 2022, the code was always broken—it just wasn't caught before.
Final word: Don't waste time on firewall rules, DNS settings, or permissions. 0XC0030059 is a coding error. Find the handle lifecycle bug and squash it.
Was this solution helpful?