0X000000AD

ERROR_CANCEL_VIOLATION (0x000000AD) Fix for Windows Lock Cancel Bug

Windows Errors Intermediate 👁 7 views 📅 Jun 20, 2026

You get this error when trying to cancel a file lock that doesn't exist yet. The fix is to check the lock order in your code or driver.

Yeah, this error is a head-scratcher. You're trying to cancel something, and Windows tells you "you never asked for this lock in the first place." Annoying. Especially when you're just trying to get a file operation done and Windows throws 0x000000AD at you. I've seen this most often in Windows 10 22H2 and Windows 11 with custom file system minifilters or when using FltCancelFileOpen or ZwCancelLockFile badly.

The Fix: Check the Lock Order

What's actually happening here is you're calling a cancel routine for a lock that was never acquired. Think of it like trying to return a book you never checked out from the library. The system keeps a record of every active lock. If you try to cancel one that doesn't exist, you get this error.

Step 1: Verify you acquired the lock before canceling it. You need to check that the lock request was submitted and is still pending. In kernel code, that means checking the return status of FltAcquireFileLock or FltAcquireResourceExclusive before calling the cancel counterpart.

// WRONG – this triggers 0x000000AD
FltCancelFileOpen(flt_instance, file_object);

// RIGHT – check first
if (SomeLockIsActive) {
    FltCancelFileOpen(flt_instance, file_object);
}

Step 2: If you're using a file system minifilter, make sure you aren't canceling a lock from a different IRP. The cancel call must match the exact lock context. If you're in a post-create callback and try to cancel a lock from a pre-read callback, it won't work. The lock region you pass must match what was originally requested.

Step 3: Use IoCancelIrp instead of the lock-specific cancel when possible. If your goal is to cancel an I/O request that's holding a lock, cancel the IRP itself. That cleans up the lock automatically. Calling FltCancelFileOpen directly is risky if you don't know the lock state.

Why This Works

The reason step 3 works is that IoCancelIrp handles the lock cleanup internally. When you cancel an IRP, the I/O manager calls the cancel routine registered with that IRP. That routine responsibly releases any locks the IRP held. But if you call FltCancelFileOpen directly, you bypass that safety net. Windows checks the cancel region against the lock table. If nothing matches, you get 0x000000AD.

Another common cause: you're canceling a lock that was already completed by another thread. This happens in multi-threaded driver code. One thread finishes the lock request, and another thread tries to cancel it. The lock table entry is gone. The fix is to synchronize your threads using a completion event or a shared flag that says "lock was already handled."

Less Common Variations

Variation 1: Wrong cancel region size

You might pass a ByteOffset and Length that don't exactly match the original lock request. For example, you locked bytes 0-4095, but try to cancel bytes 0-4096. The region mismatch gives 0x000000AD. Always use the exact same range.

LOCK_REGION region = {0, 4096}; // original lock
// When canceling:
LOCK_REGION cancel_region = {0, 4096}; // must match exactly
FltCancelFileOpen(instance, file_obj, &cancel_region);

Variation 2: User-mode application using DeviceIoControl wrong

If your user-mode code sends an IOCTL to the driver that triggers a lock cancel, but the driver never set up the lock, you get this error bubbled up. Check that your IOCTL code isn't calling cancel unconditionally. Add a check in the driver's dispatch routine to verify lock state.

Variation 3: Third-party antivirus or backup software

I've seen Sophos and Acronis trigger this on Windows 11 23H2 when they try to cancel file opens they didn't initiate. If you're not the developer, check for recent software updates. Uninstall the security software temporarily to confirm. If it fixes it, contact the vendor with the bug report.

Prevention

Stop canceling locks you didn't acquire. That's the whole secret. Write your code to check the lock status before canceling. In pseudo-code:

if (AttemptedToLock && !LockCompleted) {
    CancelPendingLock();
}

Use a state machine for your file operations. Track each lock with a boolean flag or a reference count. When you cancel, set the flag to false. When you acquire, set it to true. Simple.

For driver developers: always test with Driver Verifier enabled, specifically the I/O Verification and Lock Checking options. Driver Verifier catches mismatched lock operations and will break into the debugger before you get this error in production. Saves you hours.

One last thing: if you're writing a minifilter for Windows 10 or 11, read the Microsoft docs on FltCancelFileOpen carefully. The docs say "the caller must ensure that a lock request is outstanding for the supplied cancel region." It's not a suggestion. It's the rule.

Was this solution helpful?