Why Your Deep Links Break on iOS (And How to Fix Every Failure Mode)

Lakshith Dinesh

Lakshith Dinesh

Reading: 1 min

Updated on: Mar 12, 2026

Your iOS deep links are broken. You know this because new installs from your campaign are landing on the home screen, or the link opens Safari instead of the app, or users tapping from Instagram never reach the intended screen. What you probably don't know is which specific part of the resolution chain has failed, because iOS deep link failures are almost never accompanied by an error message. They fail silently, and users end up somewhere wrong.
iOS has six distinct failure modes for deep links, and each requires a different fix. The diagnostic steps to confirm which failure mode you're dealing with are different for each, and conflating them wastes debugging time. This guide covers all six in sequence, structured as a decision tree: identify your symptom, confirm the cause, apply the fix.
Before the failure modes, a brief explanation of how iOS resolves deep links is useful context for understanding where each failure occurs.

How iOS Deep Links Actually Resolve

When a user taps a link on iOS, the operating system determines whether to open it in an app or in Safari based on two things: whether the link is a Universal Link (HTTPS-based with a verified AASA file associated with an installed app), and whether that app is actually installed.
The resolution sequence:

  • User taps a Universal Link.

  • iOS checks its local cache of the AASA (Apple App Site Association) file for that domain.

  • If the AASA is valid and the app is installed, iOS opens the app directly, passing the URL as context.

  • If the AASA is invalid, missing, or the app is not installed, iOS falls through to Safari.

  • If Safari detects the URL redirects to an App Store URL, it navigates to the App Store.
    The AASA file is the critical dependency. It's hosted at https://[yourdomain]/.well-known/apple-app-site-association and maps URL path patterns on your domain to your app's bundle ID. iOS fetches and caches this file during app installation and refreshes it periodically. The six failure modes below map to specific points in this chain where things go wrong.
    Custom URI schemes (myapp://) bypass this process entirely, which is why they're still used as fallback routing mechanisms. They work when the app is installed, and break completely when it isn't. The Universal Link system exists to solve exactly this problem.

Failure Mode 1: AASA File Not Loading or Cached Incorrectly

Symptom: Links that worked previously now open Safari instead of the app, with no code changes on your end. The failure appeared suddenly, often after an infrastructure change.
Cause: iOS aggressively caches the AASA file per device. If the file was updated, misconfigured on a CDN, or the server configuration changed, iOS devices may continue using a stale or invalid cached version for hours or days. A common trigger is a CDN change that causes the AASA file to be served with an incorrect Content-Type header. If the header returns text/html instead of application/json, iOS silently rejects the file and falls back to Safari.
Diagnosis:
Open https://[yourdomain]/.well-known/apple-app-site-association in a browser and confirm it returns valid JSON, not an HTML error page. Check the response Content-Type header using browser developer tools or a tool like curl -I. It should be application/json or application/pkcs7-mime. Use Apple's Universal Links validation tool at https://search.developer.apple.com/appsearch-validation-tool/ to check domain configuration from Apple's perspective. Check CDN logs for any configuration changes in the period when failures started.
Fix:
Correct the AASA file content and header configuration. Ensure no CDN caching layer is overriding the Content-Type. Force a cache refresh on iOS devices by submitting a new app build to the App Store: a new binary triggers iOS to re-fetch the AASA file on the next update.
Note that iOS caches AASA files per device. Even after the file is fixed server-side, individual devices continue using the cached invalid version until their next AASA refresh. This is why AASA-related failures typically resolve gradually across your user base rather than immediately after the fix is deployed.

Failure Mode 2: Universal Link Opens Safari Instead of App

Symptom: A user taps the link on a device with the app installed. The link opens Safari and shows a webpage instead of launching the app directly.
Cause: There are three sub-causes for this failure, and identifying the correct one saves significant debugging time.
a) AASA path mismatch. The URL path in your link doesn't match any path pattern in the AASA file. If your AASA covers /products/* but the link uses /items/product-123, iOS won't recognise the link as a Universal Link and will fall through to Safari. Path patterns are case-sensitive and must match exactly.
b) Associated Domains entitlement missing or incorrect. Your Xcode project's Associated Domains entitlement must include the domain with an applinks: prefix, for example applinks:yourdomain.com. If this entitlement is absent, iOS will never attempt to open links from that domain in the app, regardless of AASA configuration.
c) User-level Universal Link disable. If a user has previously tapped a Universal Link and selected "Open in Safari" from the system prompt, iOS disables Universal Links for that domain for that user. Links will open in Safari until the user long-presses the link and selects "Open in App" from the context menu.
Diagnosis:
Confirm that the link path matches a pattern in the AASA file. Test with a link you know is covered by an AASA path. Inspect the Xcode project's Entitlements file to confirm applinks:[yourdomain] is present. Test on a fresh device that has never opened the link before: if it works on a fresh device but not on your test device, the user-level disable is the cause.
Fix:
For path mismatches, update the AASA file to cover the correct paths, or adjust the link URL format to match configured paths. For Entitlements issues, fix the Xcode configuration and submit a new build. The user-level disable cannot be reversed from the server side.

Failure Mode 3: In-App Browsers Blocking Routing

Symptom: The link works correctly in Safari and Chrome, but users who tap it inside Instagram, Facebook, Gmail, or WhatsApp don't reach the app. They see a webpage or the in-app browser opens instead.
Cause: Instagram, Facebook, and most other social and productivity apps on iOS use WKWebView-based custom browsers that do not support Universal Links. When a Universal Link is tapped inside these environments, the webview cannot trigger the native OS routing mechanism and the link falls through to the webview itself.
This is not a bug in your implementation. Universal Links in webviews require the host application to explicitly call the open(_:options:completionHandler:) API with specific options that signal to iOS that Universal Links should be handled natively. Instagram and Facebook do not implement these calls, so links inside their browsers always render as web pages. This is documented at the Apple developer level and there is no server-side or link-level workaround.
For teams running a variety of campaign types that use deep links across channels, this is the failure mode most worth designing for explicitly, because Meta placements are a primary acquisition channel and a significant share of clicks happen inside in-app browsers.
Diagnosis:
If the link works in Safari and fails inside Instagram's browser on iOS, this failure mode is confirmed. No further diagnosis is needed on the link configuration side.
Fix:
There is no fix that makes Universal Links work natively inside third-party in-app browsers. The solution is to design the fallback experience so users can still reach the app.
For acquisition campaigns on Meta placements, configure the fallback destination as a lightweight smart landing page that:

  • Detects the iOS in-app browser context and shows a prominent "Open in App" button.

  • Uses a custom URI scheme (myapp://product/123) as the "Open in App" target, which will open the app if it's installed, even from a webview.

  • For users without the app installed, shows a clearly visible App Store download CTA.
    This design means users who click from Instagram still reach the intended in-app destination, just via a one-tap web intermediary rather than a direct Universal Link resolution.

Failure Mode 4: Deferred Context Lost After Install

Symptom: New users click the campaign link, install the app, and open it to the home screen instead of the campaign destination. Deferred deep linking is configured, but new user routing is not working.
Cause: Deferred deep linking requires the SDK to initialise early enough in the app launch sequence to retrieve stored parameters from the deep linking server before any navigation decision is made. If the SDK initialises after the app's initial routing logic has already run, the deferred payload arrives too late to affect the first screen.
A secondary cause is an expired match window. If the time between the user's click and their first app open exceeds the configured match window (typically 24 hours for fingerprint-based matching), the stored parameters are discarded and the user lands on the default screen. A full breakdown of deferred matching mechanics and platform-specific success rates is available in the deferred deep links guide.
Diagnosis:
Confirm that SDK initialisation is called in application(_:didFinishLaunchingWithOptions:), before any navigation or routing logic in the app. Add logging to confirm whether the deferred deep link payload is being received by the SDK callback. If the payload is received but routing doesn't occur, the issue is in how the app handles the callback. If no payload is received, the issue is either the match window or SDK initialisation timing.
Test the deferred flow immediately after clicking the link (within 5 minutes) to rule out match window expiry as a variable.
Fix:
Move SDK initialisation to the earliest possible point in the app launch sequence. If match window expiry is the issue, extend the fingerprint match window to 48-72 hours in your deep linking platform configuration. Update to the latest SDK version, as older SDK releases may have deferred matching reliability issues that have since been patched.

Failure Mode 5: Clipboard and Pasteboard Restrictions (iOS 16+)

Symptom: Users on iOS 14+ see a system banner notification reading "[App] pasted from Safari" when they open the app after clicking a deep link. On iOS 16+, deferred routing may fail for some users, or users are presented with an unexpected permission prompt.
Cause: Some deep linking implementations use the iOS pasteboard (clipboard) to pass deferred deep link parameters. This was a viable technique before iOS 14, when clipboard access was silent. iOS 14 introduced a banner notification that appears whenever an app reads from the clipboard without direct user interaction. iOS 16 further restricted pasteboard access in certain contexts and added a permission requirement in some scenarios.
If your deep linking SDK or custom implementation uses UIPasteboard.general in its deferred matching logic, you are using this approach. The banner is not harmful to users, but it creates visible friction and erodes trust, particularly in fintech, healthcare, and other apps where users are sensitive to data handling.
Diagnosis:
Ask your engineering team whether the deep linking SDK reads from UIPasteboard.general during app initialisation. If you see "pasted from" banners in your app on iOS 14+, this is confirmed.
Fix:
Migrate to server-side fingerprint matching or use a deep linking SDK that has removed clipboard-based deferred matching. Most modern SDKs have either eliminated this method or made it opt-in with appropriate user disclosure. This typically requires an SDK update rather than an architectural change. Platforms that use fingerprint matching or Google Install Referrer (on Android) as the primary deferred matching mechanism don't have this issue.

Failure Mode 6: ATT Consent Flow Interrupting the Deep Link Journey

Symptom: Users who grant ATT consent reliably reach the correct deep link destination. Users who decline ATT or who encounter the ATT prompt during their first session sometimes land on the home screen instead.
Cause: ATT (App Tracking Transparency) prompts are modal system dialogs that pause all foreground app activity until the user responds. If the ATT prompt appears before the deep linking SDK has completed its deferred matching callback, the timing conflict can interrupt the routing process. The SDK's callback may time out or the routing decision may be made before the callback returns, sending the user to the default screen.
A second dynamic: users who decline ATT have reduced matching accuracy in fingerprint-based deferred deep linking, because IDFA is unavailable. This doesn't cause complete routing failures, but it lowers the deferred match success rate for this segment, meaning a higher proportion of users who decline ATT end up on the fallback screen.
Diagnosis:
Test the deferred install flow twice: once accepting ATT consent and once declining. If routing works correctly for the accept case but fails or has significantly lower reliability for the decline case, the issue is matching accuracy rather than timing. If routing fails for both cases (including the ATT accept), the prompt timing may be interfering with SDK initialisation.
Fix:
Defer the ATT prompt until after the deep linking SDK's deferred matching callback has resolved. This is achievable by triggering the ATT request only after the SDK's completion block fires. Most attribution and deep linking SDKs provide a mechanism to delay the ATT prompt. Note that Apple's own Human Interface Guidelines discourage showing the ATT prompt immediately on launch, so deferring it aligns with both technical and UX best practices.
For the matching accuracy gap in declined-ATT users, design the fallback experience (the screen shown when deferred routing fails) to communicate the campaign offer clearly. A fallback that mirrors the ad creative reduces the conversion loss from users who are correctly installed but not correctly routed.

The iOS Deep Link Debug Toolkit

These tools support the diagnostic steps described above:
AASA validator: https://search.developer.apple.com/appsearch-validation-tool/ checks AASA file validity and domain configuration from Apple's servers.
curl header inspection: curl -I https://[yourdomain]/.well-known/apple-app-site-association returns the HTTP response headers. Confirm Content-Type is application/json, not text/html.
Xcode Universal Links logging: Enable Universal Link decision logging with log stream --predicate 'subsystem == "com.apple.universallinks"' in the terminal while your device is connected. This shows real-time iOS decisions about whether to open links in apps or Safari.
Charles Proxy or Proxyman: Intercepts HTTP and HTTPS traffic from a real device. Useful for confirming whether the AASA file fetch succeeds and what the server returns, particularly when debugging CDN-related caching issues.
Direct Safari test: Before anything else, paste the link into Safari's address bar on a device with the app installed. If it opens the app, your Universal Link configuration is correct and the failure is environment-specific (in-app browser, deferred timing, ATT interaction). This rules out the most common AASA and Entitlements issues in one step.

Prevention Checklist: Catching Breaks Before Campaigns Go Live

Before any campaign using iOS deep links launches:

  • Validate AASA file returns valid JSON with Content-Type application/json at /.well-known/apple-app-site-association.

  • Confirm Associated Domains entitlement includes applinks:[yourdomain] in the Xcode project.

  • Test installed-app routing in Safari on the latest iOS version.

  • Test routing from inside Instagram's in-app browser on iOS. Confirm fallback behaviour for this environment is designed and working.

  • Complete the deferred install test on a real iPhone: uninstall app, click link from the intended channel, install from the App Store, verify correct destination on first open.

  • Confirm attribution parameters pass through the deferred install test correctly in the MMP dashboard.

  • Test on iOS 16+ to confirm no clipboard-related banners appear.

  • Verify ATT prompt is triggered after the SDK's deferred matching callback, not before.
    Running this checklist before launch catches failure modes 1 through 6. Most failures are silent in production, which means the only way to know a campaign is routing correctly is to have tested it explicitly before spend goes live.
    For teams experiencing recurring iOS deep link issues across multiple campaigns, the implementation decisions that underpin these failure modes (AASA hosting, in-app browser fallback design, SDK initialisation order, deferred matching method) benefit from using a platform that manages them centrally rather than handling each in isolation. Linkrunner handles AASA management, in-app browser detection, and fallback routing as part of its link infrastructure, reducing the surface area for the most common iOS failure modes. Request a demo to see how the platform handles iOS routing reliability in practice.

Frequently Asked Questions

Why does the deep link work in testing but break in the live campaign?
Testing is typically done in Safari or Chrome. Live campaigns run in Instagram, Facebook, or Gmail in-app browsers. These are different environments with different Universal Link handling behaviour. Always test from the same channel environment the campaign will run in.
Does Apple provide a way to make Universal Links work inside Instagram and Facebook?
No. Universal Links in webviews require the host app to explicitly implement an API call. Instagram and Facebook do not implement this call. The only approach is to build a fallback experience that handles the in-app browser case, as described in Failure Mode 3.
How do iOS updates affect deep link reliability?
Major iOS versions occasionally change Universal Link behaviour. iOS 16 tightened pasteboard access. iOS 14.5 changed fingerprint-based matching availability through ATT. After any major iOS release, run the prevention checklist on the new OS version to confirm existing links still function as expected.
What's the difference between a Universal Link failing and a fallback working correctly?
If the fallback is a well-designed smart landing page that routes the user to the app via a custom URI scheme, the experience can be nearly seamless even when the Universal Link doesn't resolve. The distinction matters for attribution: the fallback path must still pass attribution parameters to your MMP so the install is correctly attributed to the campaign.
Can the AASA file be served from a CDN?
Yes, but with care. The Content-Type header must be application/json. The file must be accessible over HTTPS without redirect. Some CDNs introduce caching headers that interfere with Apple's periodic refresh of the AASA file on-device. Test the full AASA response including all headers after any CDN configuration changes, using the AASA validator tool and curl header inspection.

Empowering marketing teams to make better data driven decisions to accelerate app growth!

Handled

2,199,091,969

api requests

For support, email us at

Address: HustleHub Tech Park, sector 2, HSR Layout,
Bangalore, Karnataka 560102, India

Empowering marketing teams to make better data driven decisions to accelerate app growth!

Handled

2,199,091,972

api requests

For support, email us at

Address: HustleHub Tech Park, sector 2, HSR Layout,
Bangalore, Karnataka 560102, India