Glossary/Failure modes
Clearing the AASA cache
Definition
Clearing the AASA cache means invalidating one of the three separately-expiring copies of a domain's association data: Apple's CDN copy, the device's stored association, and the app's install-time state.
The frustration of a corrected file that changes nothing comes from treating this as one cache when it is three, each with a different owner and a different way to invalidate. Two of the three you can clear on a device in front of you. The one that governs your actual users — Apple's CDN — you can only wait out, which makes it the constraint worth planning around rather than fighting.
The three layers
| Layer | Holds | Clears when | Affects |
|---|---|---|---|
| Apple's CDN | A fetched copy of your file, per domain | Apple re-fetches on its own schedule — up to 24 hours | Every user. The only one that matters for production |
| Device association store | The association the device was given | App install, app update, or swcutil reset on macOS | One device |
| Per-domain user preference | "Open this domain in Safari, not the app" | Long-press a link → Open in “App”, or reinstall | One device, and it is not really a cache |
The third row is the one that wastes the most time
It is not a cache and no amount of file work touches it. If Universal Links fail on one device and work everywhere else, you are almost certainly looking at a user preference set by tapping the domain breadcrumb in the status bar. Universal Links stopped working covers it in full.
Clearing it on a device you are holding
For development, the fastest route is to take the CDN out of the path entirely. Adding ?mode=developer to the entitlement makes the device fetch your origin directly on every launch — no CDN, no propagation delay, edits live immediately.
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:example.com</string>
<!-- Direct fetch, no CDN, no waiting. Development builds ONLY:
this makes every launch depend on your origin being up. -->
<string>applinks:staging.example.com?mode=developer</string>
</array>This also requires enabling Settings → Developer → Associated Domains Development on the device. The Developer menu only appears once the device has been used with Xcode.
# Force a fetch now and print the reason for any failure.
# The most useful diagnostic on the platform.
swcutil dl -d example.com
# What the system currently holds for the domain
swcutil show --domain example.com
# Clear the local Shared Web Credentials cache entirely, then re-fetch
sudo swcutil reset
# What Apple's CDN is handing out — unaffected by anything above
curl -sS https://app-site-association.cdn-apple.com/a/v1/example.com- Delete the app. This drops the device's association for that app.
- Reboot if you have been changing entitlements — association state survives an app delete more stubbornly than it should.
- Reinstall. Association is fetched at install, so this is the moment the new file is read.
- If it still fails,
swcutil dl -d yourdomain.comfrom macOS and read the reason rather than guessing.
The CDN, which you cannot clear
There is no purge endpoint, no developer console button, and no supported way to ask Apple to re-fetch. The CDN refreshes when it refreshes — allow up to 24 hours, and occasionally longer. Three consequences follow, and all three are worth designing around.
A fix is not live when you deploy it. Deploying a corrected file and immediately testing on a fresh install tests the CDN's old copy, not your fix. Confirm the origin is correct with curl, then check the CDN copy separately, and only conclude something is still broken when the two disagree *and* enough time has passed.
A break is not live when you cause it. This is the more dangerous direction. You can break the file today and have everything keep working for weeks on the cached copy, until the refresh lands and links fail with no correlated deploy. The change that caused the outage may be well outside the window anyone is looking at.
Existing installs are insulated either way. Devices hold the association from install time, so a CDN refresh that picks up a broken file breaks new installs first and existing users only as they update. A failure that affects only new installs is a strong signal that the file is currently broken; one that affects only recent updaters points at the app's entitlement instead.
curl -sS https://app-site-association.cdn-apple.com/a/v1/example.com \
| python3 -m json.tool > /tmp/cdn.json
curl -sS --max-redirs 0 \
https://example.com/.well-known/apple-app-site-association \
| python3 -m json.tool > /tmp/origin.json
diff /tmp/cdn.json /tmp/origin.json \
&& echo "In sync — the CDN is not your problem."Android, for comparison
Android has no CDN in the path — the device fetches assetlinks.json from your origin directly at install time — so a corrected file is live the moment it deploys. What Android does cache is the *verdict*, and it does not re-check because you changed the file.
# Re-run verification against the current file, no reinstall required
adb shell pm verify-app-links --re-verify com.example.shop
# Then read the result (verification is asynchronous)
adb shell pm get-app-links com.example.shop| iOS | Android | |
|---|---|---|
| Who fetches the file | Apple's CDN, then the device | The device, directly |
| Delay between deploy and live | Up to 24 hours | None |
| Force a re-check without reinstalling | ?mode=developer on dev builds only | pm verify-app-links --re-verify |
| Can you purge the upstream cache | No | There is nothing to purge |
| Cached on the device | The association | The verification verdict |
deep link debugger
It fetches Apple's CDN copy and your live origin in the same pass and shows you whether they agree — which is the question the caching layers make hard to answer, and the one that tells you whether to keep debugging or just wait.
Open the deep link debugger →Frequently asked questions
- How do I clear the AASA cache on iOS?
- There are three separate caches. The device's association clears when you delete and reinstall the app. A per-domain preference to open in Safari clears by long-pressing a link and choosing Open in App. Apple's CDN copy cannot be cleared at all — it refreshes on Apple's own schedule, taking up to 24 hours, and there is no purge endpoint or console option.
- How long does Apple cache the apple-app-site-association file?
- Apple's CDN refreshes its copy on its own schedule, and up to 24 hours is the figure to plan around. Devices separately cache the association from when the app was installed and do not re-fetch because the file changed, so both a CDN refresh and an app reinstall are needed before a fix reaches an existing user.
- How do I force iOS to re-fetch the AASA file?
- Add ?mode=developer to the domain in the Associated Domains entitlement and enable Settings, Developer, Associated Domains Development on the device. That bypasses Apple's CDN and makes the device fetch your origin directly on every launch, so edits take effect immediately. It must be removed before shipping, because it turns your origin into a dependency of every app launch.
- What does swcutil do?
- It is the macOS command-line tool for Shared Web Credentials and associated domains. swcutil dl -d yourdomain.com forces a fetch and prints the reason for any failure, which is the most informative diagnostic Apple provides. swcutil show --domain displays what the system currently holds, and sudo swcutil reset clears the local cache entirely.
- Why do Universal Links work for existing users but not new installs?
- Existing installs are running on an association fetched when they installed, before the break. New installs fetch the current copy and fail. That pattern is a strong signal that the file is broken right now. The reverse — only recent updaters affected — points at an app update that shipped without the Associated Domains entitlement instead.
- Does Android have the same caching problem as iOS?
- No, because there is no CDN in the path. Android devices fetch assetlinks.json from your origin directly at install time, so a corrected file is live as soon as it deploys. Android does cache the verification verdict, but a single command clears it: adb shell pm verify-app-links --re-verify followed by the package name, with no reinstall required.
Related terms
- AASA file not found — An AASA file not found error means Apple's content delivery network could not retrieve a usable apple-app-site-association file from a domain, which disables Universal Links for that domain entirely.
- Universal Links stopped working — Universal Links that previously worked and no longer do have almost always been broken by a change outside the app: a per-domain user preference, a signing or infrastructure change, or Apple's CDN refreshing its cached copy of a file that was already broken.
- Apple App Site Association (AASA) — The apple-app-site-association file is a JSON document hosted at a domain's /.well-known/ path that tells iOS which app is allowed to handle which URLs on that domain.