Summary
I'm implementing NEURLFilter with the com.apple.developer.networking.networkextension.url-filter-provider entitlement for a system-wide URL filtering feature. The feature works perfectly in development-signed builds (connecting successfully to my PIR server over extended testing) but every production-signed build fails before any network call is made.
NEURLFilterManager reports .serverSetupIncomplete (code 9). After installing the NetworkExtension debug profile, the unredacted com.apple.CipherML logs reveal the cause: no privacy proxy is provisioned for this bundle identifier, and the connection is configured proxy fail closed.
Environment
- iOS 26
- Entitlement:
com.apple.developer.networking.networkextension.url-filter-provider - Extension point:
com.apple.networkextension.url-filter-control - PIR server configured via
NEURLFilterManager.setConfiguration(...) - Privacy Pass issuer configured
- Dev-signed builds: working correctly, connecting to the PIR server
- Production-signed builds (both TestFlight and distribution): failing identically
The Error Chain
Surfaced to the app via NEURLFilterManager.lastDisconnectError:
NEURLFilterManager.Error.serverSetupIncomplete (code 9)
← NEAgentURLFilterErrorDomain Code 3
← com.apple.CipherML Code 1100 "Unable to query status"
← com.apple.CipherML Code 1800 (error details were logged and redacted)
After installing the VPN (NetworkExtension) debug profile, the unredacted com.apple.CipherML subsystem shows:
queryStatus(for:options:) threw an error:
Error Domain=NSURLErrorDomain Code=-1009
"The Internet connection appears to be offline."
UserInfo={
_NSURLErrorNWPathKey = satisfied (Path is satisfied),
interface: en0[802.11], ipv4, dns,
uses wifi, LQM: good,
NSErrorFailingURLKey = https://<my-pir-server>/config,
NSUnderlyingError = {
Error Domain=NSPOSIXErrorDomain Code=50 "Network is down"
},
_NSURLErrorPrivacyProxyFailureKey = true,
NSLocalizedDescription = "The Internet connection appears to be offline."
}
The critical diagnostic line in the com.apple.network subsystem is:
nw_endpoint_proxy_handler_should_use_proxy
Proxies not present, but required to fail closed
And the connection setup shows the proxy fail closed flag is mandatory for the connection:
[C... ... Hostname#...:443 quic,
bundle id: <my-bundle-id>,
attribution: developer,
using ephemeral configuration,
context: NWURLSession (sensitive),
proxy fail closed] start
The network path itself is healthy (Wi-Fi good, DNS resolves correctly), but the connection is explicitly configured to fail closed if no proxy is present, and no proxy is provisioned for this bundle identifier. The entire failure happens in approximately 18 ms, far too fast for any network round-trip, confirming no traffic ever leaves the device.
What I've Verified
- The entitlement is present in the distribution build
- The
NEURLFilterControlProviderextension loads and returns a valid Bloom filter prefilter (with a tag that round-trips correctly between extension and framework) NEURLFilterManager.setConfiguration(pirServerURL:pirPrivacyPassIssuerURL:pirAuthenticationToken:controlProviderBundleIdentifier:)accepts all four parameters without error- Development-signed builds of the same bundle identifier connect successfully to the same PIR server
- On production-signed builds, zero requests reach the PIR server — failure is purely client-side, before any network activity
The Question
How does the OHTTP privacy proxy get provisioned for a bundle identifier so that production builds can successfully use NEURLFilter?
Specifically:
-
Is there a Capability Request form I need to submit for
url-filter-provider? I cannot find one in the Capability Requests section of my developer portal. -
Should I be running my own OHTTP gateway (for example using
swift-nio-oblivious-http), and if so, does Apple then need to provision routing from their OHTTP relay to my gateway URL? -
Is the OHTTP relay path meant to be automatic once the entitlement is active, and if so, is there a specific activation step I'm missing?
-
Is there any way to verify the current provisioning state for a specific bundle identifier from the developer portal?
I can provide the full sysdiagnose and unredacted bundle/server details privately to an Apple engineer if that would help diagnose. I'd prefer to keep them out of a public post.
Thanks!