How to handle stale locks with WOPI

I have implemented a custom WOPI server. I’m testing it with the Docker image. Things are mostly working, but when a leftover lock is present, the user just sees a generic “sorry editor could not be loaded” message. The docker document server logs show :wopi error LOCK:AxiosError: Request failed with status code 409". The server is returning the 409 with the correct headers indicating the current lock and lock reason. Is this the intentional behavior? Is there a way to show a meaningful message to the user so they could be given an opportunity to override the lock if they have permission? I can’t find anything in the documentation about what happens after the wopi server returns the 409. Thanks.

Hello @bdeter
The code 409 means the conflict with the current lock:Lock | Microsoft Learn
However, the entire scenario is still unclear. Could you please reproduce the situation and record a video file? Once the situation is reproduced, please collect entire Document server logs folder.

Additionally, please specify Docs version, installation type and server OS.

Thanks for responding.

Version: 9.0.2. Build: 9

In this scenario, I ended up with a bad lock so the server returned a 409 with:

{"X-WOPI-Lock":"3","X-WOPI-Version":0,"X-WOPI-LockFailureReason":"Existing: 3, New: 1"}

The document server correctly detected that:

[2025-07-02T23:56:04.157] [DEBUG] [localhost] [1] [userId] nodeJS - wopi LOCK request uri=http://host.docker.internal:8001/api/wopi/files/1?access_token=... headers={"X-WOPI-Override":"LOCK","X-WOPI-Lock":"1","X-WOPI-Proof":"...","X-WOPI-ProofOld":"...","X-WOPI-TimeStamp":"638870973641540000","X-WOPI-ClientVersion":"9.0.2.9"}
[2025-07-02T23:56:04.157] [DEBUG] [localhost] [1] [userId] nodeJS - isAllowDirectRequest url in jwt token res=true
[2025-07-02T23:56:04.162] [ERROR] [localhost] [1] [userId] nodeJS - wopi error LOCK:AxiosError: Request failed with status code 409
    at settle (/snapshot/server/Common/node_modules/axios/dist/node/axios.cjs)
    at IncomingMessage.handleStreamEnd (/snapshot/server/Common/node_modules/axios/dist/node/axios.cjs)
    at IncomingMessage.emit (node:events:536:35)
    at endReadableNT (node:internal/streams/readable:1698:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
    at Axios.request (/snapshot/server/Common/node_modules/axios/dist/node/axios.cjs)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.postRequestPromise (/snapshot/server/Common/sources/utils.js)
[2025-07-02T23:56:04.162] [INFO] [localhost] [1] [userId] nodeJS - wopi LOCK end

But the error shown to the user was “Sorry, editor could not be loaded. Please contact your administrator.”

Is that the correct behavior and message? The administrator wouldn’t have much information to work with. I turned on full logging for this test, but with normal WARN logging, there is no information about the file or any identifying information that would let me know how to fix it.

Thanks

It seems that the situation is related to an incorrect lock, but we need the exact step-by-step scenario to check whether it’s expected behavior or not. Please provide it to us.

  1. Create a custom wopi server
  2. Set up a client application using the Docker document server with the custom wopi server
  3. Create a document and have the wopi server save it
  4. Change the wopi server to force it to return an incorrect lock. This simulates a situation where a bug or system crash incorrectly keeps a lock on the document
  5. Refresh the document editor
  6. The editor will display the generic Contact an Administrator message
  7. The default document server logs in warn level will show there was a 409, but will not indicate anything useful about what document was or what the lock was or was expected to be.
  8. If you change the server logging to All, you will see information about the lock.

I’m trying to understand how to handle scenarios such as this. If a user comes to me saying they got that message, where should I go to find out what happened? If the answer is to change the logging level and have them try again, that’s fine, I just want to make sure I’m not missing some information like an admin page or additional logging.

Thanks

Thank you for detailed description. Indeed, the current behavior is expected. However, it seems that we need to determine whether any changes to this behavior are necessary and for logs to facilitate diagnosis.
We need some time to discuss the situation internally, I will contact you shortly.