iOS 27: domain-bound SMS one-time codes are not offered in an associated app ("Could not fetch application record"), worked on iOS 26.6 and 18

Since iOS 27.0, domain-bound SMS one-time codes are no longer offered above the keyboard in our app, where the code is entered on a web page in a WKWebView, although the app is associated with the domain through webcredentials. The same SMS is offered in Safari on the same device, and it is offered in our app on iOS 26.6 and iOS 18.

SMS format (last line per the domain-bound code format):

Your verification code is: 123456

@app.example.com #123456

Setup

  • Several builds of the same app with different bundle IDs (App Store, internal, development), all under one team
  • Entitlement com.apple.developer.associated-domains: webcredentials:app.example.com (plus two more environments of the same domain)
  • AASA at https://app.example.com/.well-known/apple-app-site-association: 200, application/json, no redirect, same content on app-site-association.cdn-apple.com:
    {"webcredentials":{"apps":["TEAMID.com.example.app","TEAMID.com.example.app.internal","TEAMID.com.example.app.dev"]}}
    
  • The code field is an <input type="tel" autocomplete="one-time-code"> in a WKWebView showing a page on that domain. We also tested a native field with the one-time-code content type (the app is built with Flutter; the field is a Flutter TextField with the one-time-code autofill hint).

Steps

  1. Open the verification page in the app and focus the code field.
  2. Receive the SMS above.

Expected: the code is offered in the QuickType bar, as it is in Safari on the same domain and as it is in our app on iOS 26.6 and iOS 18.

Actual: nothing is offered. The keyboard log:

kbd  Received verification code from Messages
kbd  One Time Code field has been entered.
kbd  Retrieving Current One-Time Codes for App
kbd  Current verification code is domain-bound to <mask.hash: '…'>.
kbd  Domain-bound verification code is NOT valid for app <mask.hash: 'X'>.
E kbd Could not fetch application record for application identifier: <mask.hash: 'X'>.
kbd  Returning 0 available one-time codes

What we checked

  • swcd downloads the AASA for all domains without errors after a reinstall.
  • The installed app's entitlements (read from the device) contain the expected application-identifier and associated domains; the profile is validated.
  • The failure is the same in the WKWebView field and in a native one-time-code field, in the App Store build, a distribution-signed internal build and a development build, and in an older app version that used to work.
  • The masked application identifier in the log (X above) is the same for two builds with different bundle IDs, so the lookup does not seem to use the app's bundle ID. All our builds share CFBundleExecutable = Runner (the Flutter default) and the same CFBundleName.
  • The same app build and the same SMS work on iOS 26.6 and iOS 18.x, so the change happened between iOS 26.6 and 27.0.
  • An SMS without the @domain #code line is offered in the app on iOS 27 (Returning 1 available one-time code), although Could not fetch application record is still logged.

Questions

  1. Is this a known iOS 27 regression, or is there a new requirement for apps to receive domain-bound codes?
  2. What application identifier does the keyboard use for this lookup, and can anything in the app's configuration (for example the executable name) affect it?

Device: iPhone 17 Pro Max, iOS 27.0

Thanks for the post this is very interesting.

Starting with the error Could not fetch application record suggest standard SMS codes do not require this strict entitlement validation to work to the active foreground app, which explains why standard codes still work for you despite the lookup error being logged?

The app looks like you are using Flutter so I can’t comment about the autofill and how that work in that 3rd party tool. The subsystem might be incorrectly hashing a shared attribute like CFBundleExecutable (which defaults to "Runner" in Flutter) or CFBundleName instead of the actual Bundle ID.

I don’t see anything wrong about your AASA file, the structure properly uses the webcredentials dictionary containing an apps array, and the app identifiers are correctly formatted using the required <TeamID>.<BundleID> convention. Even though you didn’t provide the link to the file, I’m guessing is synced to the CDN servers?

Albert  WWDR

Thanks, Albert.

CDN: yes, the AASA is on the CDN. https://app-site-association.cdn-apple.com/a/v1/app.example.com returns the same JSON as the domain, and after installation swcd approves the webcredentials entry for that domain.

Flutter: to rule it out, we built a minimal native app and tested it on the same iPhone (iOS 27.0):

  • new Xcode project, SwiftUI, no third-party code
  • the bundle ID of our development build, signed with the team's development profile
  • entitlement webcredentials:app.example.com
  • a UITextField with textContentType = .oneTimeCode
  • a WKWebView with <input autocomplete="one-time-code"> on a page whose origin is https://app.example.com

SMS sent from another phone:

Your verification code is: 123456

@app.example.com #123456

The code is not offered in either field. Keyboard log for the native UITextField:

kbd  Received verification code from Messages
kbd  Current verification code is domain-bound to <mask.hash: 'D'>.
kbd  Checking domain against associated domains for app <mask.hash: 'A'>.
kbd  Domain-bound verification code is NOT valid for app <mask.hash: 'A'>.
kbd  Returning 0 available one-time codes

The WKWebView field logs the same lines, plus Could not fetch application record for application identifier: <mask.hash: 'A'> before the domain check. So the lookup error is not the cause: the native field has no lookup error, and the domain check still fails.

Executable name: we built the same native app again with PRODUCT_NAME = Runner (so CFBundleExecutable = Runner) and changed nothing else. It fails the same way, and the masked application identifier is identical to the first build's. So the identifier does not come from the executable name.

Summary: on iOS 27.0, a native app without third-party code, whose webcredentials association swcd has approved, is not offered a domain-bound SMS code for that domain. This happens in a native field and in a WKWebView. The same SMS is offered in Safari on the same device, and the same setup worked on iOS 26.6 and iOS 18.

Why the SMS carries the domain: we add the @app.example.com #123456 line on purpose, to follow the origin-bound one-time code format (also used by the WebOTP API). It lets browsers and associated apps fill the code, and only on the right domain, which protects against phishing. Dropping the line makes the code appear in our app again on iOS 27, but it also drops that binding to the domain. We would rather keep the standard format and have it work in the associated app, as it did before iOS 27.

Can you confirm whether this is a regression in iOS 27, or a new requirement that apps have to meet?

Thanks for your reply, I don't think you gave me the correct link to your AASA file as returns a 404 missing file:

curl -v https://app-site-association.cdn-apple.com/a/v1/app.example.com
* Host app-site-association.cdn-apple.com:443 was resolved.
* IPv6: 2620:149:a21:f000::196, 2620:149:a21:f000::135, 2620:149:a00:0:17:253:253:7, 2620:149:a00:f000::133, 2620:149:a00:0:17:253:253:4, 2620:149:a00:f000::151, 2620:149:a0c:f100::4, 2620:149:a0c:f000::1
* IPv4: 17.253.5.150, 17.253.253.4, 17.253.83.199, 17.253.253.8, 17.253.17.202, 17.253.83.150, 17.253.17.211, 17.253.5.142
*   Trying [2620:149:a21:f000::196]:443...
* Connected to app-site-association.cdn-apple.com (2620:149:a21:f000::196) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: C=US; ST=California; O=Apple Inc.; CN=app-site-association.cdn-apple.com
*  start date: Sep 22 23:52:36 2026 GMT
*  expire date: Dec 15 20:17:55 2026 GMT
*  subjectAltName: host "app-site-association.cdn-apple.com" matched cert's "app-site-association.cdn-apple.com"
*  issuer: C=US; O=Apple Inc.; CN=Apple Public Server ECC CA 1 - G1
*  SSL certificate verify ok.
* using HTTP/1.x
> GET /a/v1/app.example.com HTTP/1.1
> Host: app-site-association.cdn-apple.com
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 404 Not Found
< Server: AppleHttpServer/7b3d349ae60c243cdd677edbde3e93e460f75820
< Date: Fri, 23 Oct 2026 14:06:51 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 10
< Apple-Failure-Reason: SWCERR00202 Connections to private/reserved IP addresses are not allowed
< Apple-From: app.example.com
< Apple-Try-Direct: false
< Cache-Control: max-age=3600,public
< Vary: Accept-Encoding
< X-B3-TraceId: 2b4b48a7bd65e107
< Strict-Transport-Security: max-age=31536000
< Age: 0
< Via: https/1.1 usmsc2-3p-pac-009.ts.apple.com (acdn/25.17695), https/1.1 usmsc2-3p-pfe-001.ts.apple.com (acdn/25.17695), https/1.1 uslax1-edge-mx-018.ts.apple.com (acdn/25.17695), https/1.1 uslax1-edge-fx-052.ts.apple.com (acdn/25.17695)
< X-Cache: miss, miss, miss, miss
< CDNUUID: 0eed0575-9eec-4de5-bdb4-1862da644b1b-136513017
< Connection: keep-alive
< 
Not Found
* Connection #0 to host app-site-association.cdn-apple.com left intact

Albert  WWDR

Thanks, Albert, and sorry for the confusion. app.example.com was a placeholder: I anonymized the domain, team ID and bundle IDs in the post, and example.com is a reserved domain, which is why the CDN reports SWCERR00202.

The real domain is app.digisign.org:

$ curl -i https://app-site-association.cdn-apple.com/a/v1/app.digisign.org
HTTP/1.1 200 OK
Content-Type: application/json

{"webcredentials":{"apps":["33F646XBSF.com.ds.digisign.internal","33F646XBSF.com.ds.digisign.dev","33F646XBSF.com.ds.digisign"]}}

The origin https://app.digisign.org/.well-known/apple-app-site-association serves the same JSON (200, application/json, no redirect).

The values from my previous reply, unmasked:

  • Native test app: bundle ID com.ds.digisign.dev, team 33F646XBSF, entitlement webcredentials:app.digisign.org, development signing. After installation swcd approved the webcredentials entry for app.digisign.org.
  • SMS last line: @app.digisign.org #123456
  • WKWebView page origin: https://app.digisign.org
  • Our App Store app (com.ds.digisign) fails the same way on iOS 27.0.

I'd like to add that this is also ocurring in our app, reproduced on iOS 27.2 (24B115), iPhone 13 mini, native UIKit app, so it isn't specific to Flutter or to 27.0. I first experienced this in the iOS 27 public betas.

App: love.realestate.app.ios (team U8G44Y5EBF), App Store build 2.84.0 (486). CFBundleExecutable and CFBundleName are both Listed.

Our entitlement is for webcredentials for the domain listed.inc. Apple's CDN serves our AASA with "webcredentials": {"apps": ["U8G44Y5EBF.love.realestate.app.ios"]}.

We also have applinks and activitycontinuation set to the domain, and those work fine.

Message example

Your Listed sign in code is: 123456

@listed.inc #123456

This format has worked for years, including in iOS 26.

On 27.2:

  • Domain-bound message → no suggestion in the app whether in the App Store–signed TestFlight build or in development-signed debug and release builds.
  • Same message without the @listed.inc #… line → suggested and fills (UITextField, textContentType = .oneTimeCode, keyboardType = .asciiCapableNumberPad).
  • Safari, in the companion web app on https://listed.inc → the code in the domain-bound message is offered as a suggestion and fills.

Keyboard log (kbd, subsystem com.apple.mobilesafari, category AutoFill), identical for every bound attempt across different builds (development, release/TestFlight):

Received verification code from Messages: <mask.hash: (null)>
(SafariFoundation) Retrieving Current One-Time Codes for App
Current verification code is domain-bound to <mask.hash: '1ZdP4qzQfOzw6i3/aSXytA=='>.
Domain-bound verification code is NOT valid for app <mask.hash: '1ZdP4qzQfOzw6i3/aSXytA=='>.
Fetching passwords for associated domains for app <mask.hash: '1ZdP4qzQfOzw6i3/aSXytA=='>.
Returning 0 available one-time codes

Two observations on that: the same masked value appears in the "domain-bound to" slot and in both "for app" slots, which fits your finding of one hash across two bundle IDs, and the Could not fetch application record error from your 27.0 logs does not appear on 27.2, yet the outcome is the same. No swcd activity is logged in the seconds around the check. An unbound message in the same session logs Returning 1 available one-time code:

Received verification code from Messages: <mask.hash: (null)>
Retrieving Current One-Time Codes for App
Returning 1 available one-time code

We're now sending non-domain-bounded SMS code messages to users on iOS 27, until this is fixed.

I haven't submitted a Feedback issue since I've never had luck getting my Feedback resolved over the years, so I no longer bother. This public forum is better for visibility anyway.

We can add reproduction data from another app, HTN, on iPhone 17e (iPhone18,5), iOS 27.0.1 (24A446). The domain-bound symptom matches this thread, but our unbound-message results differ, so we are not assuming the same root cause.
Environment: Flutter 3.35.6 (engine d2913632a4), Dart 3.9.2, Xcode 26.5 (17F42). App version 2.2.6; the instrumented local builds are development-signed profile builds. The user also reports that an older published version, previously working, now fails on the same phone; we have not established that older build number or tested a different iOS version/device.
Domain-bound case
Our SMS has this format (123456 is a dummy example, not a real login code):

codice di accesso: 123456
@e-htn.it #123456

The installed app contains application-identifier Q9SKMCAYZY.it.e-htn.htnsalute and webcredentials:e-htn.it.
Both origin AASA URLs return 200 without redirects:
https://e-htn.it/.well-known/apple-app-site-association
https://www.e-htn.it/.well-known/apple-app-site-association
Both corresponding Apple CDN URLs return 200, Content-Type: application/json and include Q9SKMCAYZY.it.e-htn.htnsalute in webcredentials.apps; all four response bodies match. One qualification: the captured origin headers did not contain Content-Type, while the CDN serves application/json. We have not independently verified the phone's internal swcd approval record.
The focused native Flutter input has textContentType = one-time-code, first responder true, attached window, nonempty frame, secure entry false, and keyboard type default.
Selected Console lines from 4 November 2026, UTC+01:00 (manually transcribed, with the system-masked hashes further redacted; not a raw logarchive):

18:03:37.181148 kbd Current verification code is domain-bound to [redacted].
18:03:37.182122 kbd Domain-bound verification code is NOT valid for app [redacted].
18:03:53.545938 kbd Current verification code is domain-bound to [redacted].
18:03:53.552573 kbd Domain-bound verification code is NOT valid for app [redacted].

Unbound SMS and same-app native comparison
We then sent fresh, six-digit dummy codes from another phone without the @domain #code line. The user confirmed that the initial unbound message is recognized in Messages: its code is underlined and tapping offers Copy Code. It was still not suggested in the app.
To compare inputs, local build 2.2.6 (13) opens an isolated diagnostic screen, without starting the normal Dart login/Health-sync flow. It does not submit the dummy codes to a backend. Only one test input is mounted at a time.
We tested both:

  • Flutter TextField: oneTimeCode hint, default system keyboard, secure false, autocorrect true.
  • UIKit UITextField: .oneTimeCode, .default keyboard, secure false, autocorrection/spellchecking .default.
    Important scope limitation: the UITextField is hosted in a Flutter platform view in the SAME app/bundle, not a separately built all-native app. .default is not forced .yes. The user reports no suggestion in either tested case. We did not separately complete the two OFF variants in this diagnostic screen.
    The focused UIKit field and its UIFieldEditor were confirmed on-device as first responders, attached to a window, nonempty frame, one-time-code content type, keyboard type 0, secure false, autocorrection type 0 and spellchecking type 0. The Flutter ON case was subsequently confirmed with the same relevant traits. The native negative observation is persisted as a boolean; the Flutter ON negative observation is user-reported. We did not capture a corresponding system candidate result for the Flutter ON case.
    In the native test session, kbd logged:
18:39:00.530838 Notifying observer [redacted] of one-time code changes
18:39:00.566670 Returning 0 available one-time codes
18:40:11.742700 One Time Code field has been entered.
18:40:11.765311 Returning 0 available one-time codes
18:40:11.857155 One Time Code field has been entered.
18:40:11.866280 Returning 0 available one-time codes

Password/passkey AutoFill is enabled in Settings. The user sees the native Apple keyboard. No cross-device/iOS-version comparison or controlled Safari/WKWebView test has been performed for our app, and we have not collected a sysdiagnose yet. Therefore, unlike the unbound workaround described above, simply dropping the domain line has NOT been demonstrated to resolve our case.
Could Apple advise which targeted logging/profile would help explain the zero candidates and distinguish association state from another eligibility issue? Is there a changed requirement for app-associated domain-bound OTPs on iOS 27? Also, has anyone tested ASWebAuthenticationSession or SFSafariViewController as a controlled browser-based comparison/potential workaround, rather than WKWebView? We would test a genuine HTTPS authentication flow with a matching SMS/page domain and preserve the normal OAuth callback/PKCE, not attempt to extract an OTP from Safari.
No real OTPs, credentials, phone numbers or patient data are included here. We can provide additional sanitized input-trait snapshots and reproduction configuration if useful.