CERTSRV_E_BAD_REQUESTSTATUS (0x80094003) Fix: Status Lock in AD CS
This error means the certificate request's status (pending/denied) blocks the operation. The fix is resetting the request status in the CA database.
You got this error after submitting a certificate request
It's maddening. You filled out the CSR, hit submit, and then the CA throws 0x80094003 back at you. The literal meaning: the request's current status doesn't allow the operation you're trying to do. What's actually happening here is that the Certificate Authority has locked the request into a state—pending, denied, or issued—and you're trying to do something that contradicts it, like resubmitting a denied request or approving an already-issued one.
The fix: reset the request status using certutil
The fastest way out is to delete or resubmit the request from the CA's perspective. But you don't want to lose the request ID if you need to track it. So here's what works:
- Open an elevated command prompt on the CA server.
- Run
certutil -config "CA-NAME\CA-NAME" -resubmit <RequestID>. Replace CA-NAME with your CA's common name (you can get this fromcertutil -config). - If the resubmit fails because the status is too far gone, use
certutil -config "CA-NAME\CA-NAME" -deny <RequestID>thencertutil -config "CA-NAME\CA-NAME" -resubmit <RequestID>to force a fresh state. - After resubmission, approve the request from the Certification Authority snap-in or via
certutil -config "CA-NAME\CA-NAME" -issue <RequestID>.
The reason step 3 works is that denying a request clears its status to a neutral state where resubmit can regenerate the request object. The CA database uses a status enum internally (0=pending, 1=issued, 2=denied, 3=error). Once it's denied, the request's row is flagged in a way that blocks most operations. Denying it again does nothing—you need to reset through resubmit. This is a documented but rarely explained behavior in AD CS.
Less common variations of the same issue
1. The request was auto-approved but then revoked
If you revoked a certificate and then try to reissue the same request ID, the CA sees the request as already processed. The fix here isn't certutil—it's generating a fresh CSR. But you can check by running certutil -config "CA-NAME\CA-NAME" -getreq <RequestID> to see the status. If it says 1 (issued), you'll need to create a new request from the client.
2. Request stuck in pending due to a misconfigured enrollment agent
When using an enrollment agent certificate that's expired or invalid, the CA might set the request to pending without allowing approval. I've seen this on Windows Server 2016+ where the enrollment agent's CA certificate chain is broken. The symptom: you approve the request, and it immediately reverts to pending. In this case, fix the agent certificate chain first, then resubmit. Don't bother with certutil until the chain is valid.
3. Multiple CA nodes in a load-balanced environment
If you have two CA servers sharing a database (like in a load-balanced pair), one node might have locked the request row. The error 0x80094003 appears because the CA you're hitting sees a different status than what the database reports—usually caused by replication lag. Wait a few minutes or force replication with certutil -pulse on the lagging node.
Prevention
The root cause is almost always human error or process mismatch: submitting a request twice, trying to approve a request that was already processed, or using an old request ID. Here's how to avoid it:
- Use unique request IDs. Don't reuse the same CSR file for multiple submissions. Each submission should be a fresh request from the client.
- Check request status before approving. In the CA snap-in, sort by status. If you see pending requests from days ago, investigate before approving them. Use
certutil -config "CA-NAME\CA-NAME" -getreq <RequestID>to print the raw status. - Automate cleanup. Run a scheduled task weekly that denies and removes requests older than 30 days:
certutil -config "CA-NAME\CA-NAME" -deny <RequestID>thencertutil -config "CA-NAME\CA-NAME" -remove <RequestID>. This keeps the database lean and prevents stale status locks.
One more thing: never manually edit the CA database in SQL Server or via ADSI Edit. I've seen admins try that and corrupt the request table. The certutil commands are safe because they go through the CA's internal API, which validates state transitions. Direct edits bypass that and can brick the CA.
Was this solution helpful?