Issues Mounting WebDAV Shares with NetFSMountURLAsync (Error 22)

Hey fellow developers,

I’m developing an app that mounts network shares (SMB, AFP, Secure WebDAV, CIFS) using the NetFSMountURLAsync function.

Recently, mounting WebDAV shares has stopped working — it fails with error code 22, but I can’t find a definitive reason for the failure. It simply doesn’t work. However, using Finder to connect to the same WebDAV share works flawlessly, so it doesn’t appear to be a server-side issue.

Strange Behavior

I’ve noticed something interesting:

If I create a new Xcode project and set Signing Certificate to Sign to Run Locally, the app mounts the WebDAV share without any issues. As soon as I change the signing option to anything else (e.g., Development), the share no longer mounts, and the app fails with error 22. Even if I switch back to Sign to Run Locally, the app remains broken and refuses to mount the share. Rebuilding the app, restarting Xcode, and clearing derived data/caches do not restore functionality. The only workaround I’ve found is to create a new Xcode project and copy the code over.

Additionally:

Mounting SMB and AFP shares always works without issues. The app is properly sandboxed. My certificates are valid until at least 2027. Granting the app Full Disk Access does not resolve the issue.

System Log Insights

Looking at the system log, I found several mounting-related messages. On failure, one stands out:

System Policy: webdavfs_agent() deny(1) file-mount <Path to the mount directory in the Documents directory of the example project>

Questions

Does anyone have any idea how to debug or resolve this issue? Is there a way to reset the example project to a working state? Are there any caches or system states I might have missed?

I’d prefer not to recreate all my certificates and configurations, as I don’t see any reason why they would affect only WebDAV mounting while everything else works fine.

Reproducing the Issue

I’ve created a minimal SwiftUI example to reproduce the problem. Just create a new macOS SwiftUI project, replace ContentView with my code, update the details to match your WebDAV share, and enable Outgoing Network Connections in the entitlements.

Any help or insights would be greatly appreciated!

Example Code

import SwiftUI
import NetFS

struct ContentView: View {
    let mounter = WebDAVMounter()
    var body: some View { VStack { Button("Test mount") { test() } } .padding() }
    func test() { mounter.mount() }
}

class WebDAVMounter {
    private var requestID: AsyncRequestID?
    func mount() {
         let username = <# username #>
         let password = <#password#>
         let serverURL = URL(string: "<#https://webfiles/Work~Home#>")!
         let usedMountPoint = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
         let openOptions = NSMutableDictionary()
         openOptions[kNAUIOptionKey] = kNAUIOptionNoUI
         let mountOpts = NSMutableDictionary()
         mountOpts[kNetFSSoftMountKey] = true
         
         print("server URL: \(serverURL) usedMountPoint: \(usedMountPoint) username: \(username) password: \(password) sessionOpts: \(openOptions) mountOptions \(mountOpts)")

         NetFSMountURLAsync(serverURL as CFURL,
                            usedMountPoint as CFURL,
                            username as CFString?,
                            password as CFString?,
                            openOptions as CFMutableDictionary,
                            mountOpts as CFMutableDictionary,
                            &requestID,
                            DispatchQueue.main,
                            { status, asyncRequestId, mountedDirs in print("mount_report: \(status), mountedDirs: \(String(describing: mountedDirs))")})
    }
}

First, off I want to focus on these details:

Mounting SMB and AFP shares always works without issues. The app is properly sandboxed.

and this error:

System Policy: webdavfs_agent() deny(1) file-mount <Path to the mount directory in the Documents directory of the example project>

...I don’t see any reason why they would affect only WebDAV mounting while everything else works fine.

Agreed. Please file a bug on this and then post the bug number back here. Setting all other issues aside, I can't think of any case where the system should deny mounting for webdav but allow SMB/AFP. This is a case where they should either all fail or all succeed.

Next a few clarification on other points:

I’d prefer not to recreate all my certificates and configurations, as I don’t see any reason why they would affect only WebDAV mounting while everything else works fine.

For future reference, there's generally not any reason to bother with this sort of "recreate everything". You can basically "split" our codesigning architecture around two questions:

  1. Is the signature "valid"? -> If it is, let the code run.

  2. What entitlements/capabilities are embedded in that signature? -> Based on that, change what the system will allow/disallow.

That leads to here:

If I create a new Xcode project and set Signing Certificate to Sign to Run Locally, the app mounts the WebDAV share without any issues.

I haven't looked the full details of the implementation, but my recollection is that locally sandboxed apps are inherently unsandboxed. Entitlements and the sandbox don't really make sense in that "local only" context, so the system doesn't bother with them.

Related to that point:

Even if I switch back to Sign to Run Locally, the app remains broken and refuses to mount the share.

There are mechanism in the system to prevent apps from masquerading as "each" other, and I think that's what tripped up here. That is, I think you had a sequence something like this:

  1. The initial, locally signed app was unsandboxed and unrestricted.

  2. The fully signed app was blocked by the sandbox.

  3. The system now thinks #1 is trying to masquerade and #2, so it blocks it.

The only workaround I’ve found is to create a new Xcode project and copy the code over.

FYI, I think simply changing the bundle ID would make #1 work again.

Any help or insights would be greatly appreciated!

So, a few things you should test:

  1. Try adding the "com.apple.security.network.client" capability. My initial read (so I may have missed something) of our code is that this is what NetAuth is looking for and it's the easiest thing to test.

  2. If #1 doesn't work, then try disabling the App Sandbox and see if that resolves the issue. This is will quickly determine whether the issue is specifically a sandbox issue (if it works) or not (if it fails), which is important to a more in depth investigation.

  3. Try setting "NULL" for the mount point (use the system mount path) and dropping kNAUIOptionNoUI. Again, both of these are to try and clarify what the system's actual issue is, not to force you to use that particular configuration.

Finally, on this point:

Looking at the system log, I found several mounting-related messages. On failure, one stands out:

If you're still having issues then I'd like to see more of the mount log data both before and after the log message you found. What's helpful here isn't just the immediate log message content, it's that (in a deeper investigation) the log messages themselves let me narrow down exactly where the failure actually occurred.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Issues Mounting WebDAV Shares with NetFSMountURLAsync (Error 22)
 
 
Q