NEURLFilter PIR status check fails with CipherML errors (Code 1100/1800)

Hello !

following up from a related thread (account transfer issue, now resolved: https://developer.apple.com/forums/thread/843546?answerId=911820022), but this is a distinct, new issue so starting fresh as suggested.

The extension launches fine, XPC handshake succeeds, and PIR registration completes successfully. But the subsequent NEPIRChecker status check fails every time (retried repeatedly over several minutes, same result each time):

PIR status returned error <Error Domain=com.apple.CipherML Code=1100 "Unable to query status due to errors: Error details were logged and redacted." UserInfo={NSLocalizedDescription=Unable to query status due to errors: Error details were logged and redacted., NSUnderlyingError=0x677037cf0 {Error Domain=com.apple.CipherML Code=1800 "Error details were logged and redacted." UserInfo={NSLocalizedDescription=Error details were logged and redacted.}}}>

Config being registered (confirmed from the logs):

pirServerURL = https://pir.dropbet.app/
pirPrivacyPassIssuerURL = https://pir.dropbet.app/issue

Both endpoints are live and were already validated as part of the original NEURL Filter configuration approval. I've captured a sysdiagnose from the device right when this was happening, so I have that ready to attach to a bug report if useful — just let me know and I'll file one.

Any idea what CipherML error 1100/1800 typically indicates?

Unfortunately those error codes don’t tell you much:

  • 1100 is basically a something failed error.
  • 1800 means something failed but we’re pretty sure that the underlying details went into the system log.

So the next step is to reproduce the problem, grab a system log snapshot, and then look up the for other log entries in the com.apple.CipherML subsystem.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi @DTS Engineer

Following up with a much more precise finding after digging into server-side logs.

The failure is happening in our PIR server's OHTTP gateway, specifically in HPKE request decapsulation:

[OHTTP] decapsulateRequest failed: Crypto.CryptoKitError.underlyingCoreCryptoError(error: 503316581)

This is thrown from HPKE.Recipient(privateKey:ciphersuite:info:encapsulatedKey:) / .open(ct, authenticating:) (DHKEM(X25519, HKDF-SHA256) / HKDF-SHA256 / AES-128-GCM, per RFC 9458).

What I've confirmed:

  • Not an entitlement/config issue
    The NEURL Filter configuration is correctly onboarded, and the client reaches this point successfully (handshake, registration all succeed first).

  • Reproducible independently of the iOS client
    I wrote a standalone Python script using a real HPKE library (pyhpke), fetched our server's published /.well-known/ohttp-gateway key, and built a byte-for-byte RFC 9458-compliant OHTTP request against it. It fails with the exact same CryptoKitError.underlyingCoreCryptoError(error: 503316581). So this isn't specific to anything the iOS client does.

  • Failure rate seems to fluctuate over server uptime
    Right after restarting the server process, a handful of real device requests briefly succeeded decryption (progressing to a later, unrelated parsing error), then it reverted to failing on essentially every attempt a few minutes later. This pattern makes me suspect a concurrency/thread-safety issue around the shared Curve25519.KeyAgreement.PrivateKey being used to construct a new HPKE.Recipient on every incoming request, rather than a static configuration problem.

Any idea what corecrypto error 503316581 typically indicates, or whether there's a known gotcha with concurrent HPKE.Recipient construction from a shared private key in swift-crypto? Happy to share the Python repro script and/or file a bug with logs attached if that would help narrow it down.

Thanks again for sticking with this one.