A Deep Link That Only Sometimes Opens the App Is Worse Than One That Never Does

Key takeaway: Deep linking configuration has enough small, easy-to-miss requirements that partial implementation is the most common outcome, and a partially working deep link is often more confusing to diagnose than one that is simply entirely absent.
Why Deep Links Fail Partially Rather Than Completely
Both major platforms require a verification step proving that the app is genuinely authorised to handle links for a specific domain — a file hosted at a well-known path on the domain, referencing the app’s identifier, which the platform checks before allowing the app to intercept links to that domain rather than opening them in a browser by default.
Getting most of this configuration right and one specific detail wrong — an incorrectly formatted verification file, a mismatched app identifier, a missing entry for one specific subdomain pattern the marketing team later starts using — produces exactly the confusing partial failure: links work in some contexts and silently fall back to opening a browser in others, with no error shown to the user and no obvious signal to the developer about which specific configuration detail is the actual cause.
The Verification Requirements Worth Checking Explicitly
| Requirement | Common failure point |
|---|---|
| Verification file hosted at the correct well-known path | Wrong path, or served with incorrect content type |
| File content matching the app’s actual identifier exactly | Copy-paste error, or using a development identifier in production |
| File served over HTTPS with a valid certificate | Works in testing, breaks if certificate expires unnoticed |
| Every subdomain that will send links covered | New marketing subdomain added later, verification not updated |
| App correctly registered to handle the domain in its own configuration | Configuration present in one build flavour, missing in another |
The subdomain coverage gap is particularly common in practice, because the initial deep linking setup is usually done once for the main domain, and a marketing or content team later begins sending links from a different subdomain for a campcampaign without anyone connecting that decision back to the original deep linking configuration that does not cover it.
Testing This Properly
Testing exclusively by tapping a link on the same device used for development, logged into the same accounts and with the app already installed and recently opened, misses several of the actual failure conditions that affect real users — testing specifically with the app not installed at all, to verify the fallback behaviour genuinely leads somewhere sensible like an app store listing rather than a broken page, and testing with the app installed but not recently opened, are both necessary to catch platform-specific caching or verification timing issues that a same-device repeated test would never surface.
Testing from an actual different context the link might realistically arrive from — a messaging app, an email client, a social media app’s in-app browser — matters too, because some of these contexts apply their own additional restrictions or in-app browser behaviour on top of the platform’s standard deep link handling, and a link that behaves correctly from a browser address bar during testing does not guarantee identical behaviour from every context users will actually encounter it in.
Designing the Fallback Deliberately
The fallback behaviour when the app is not installed deserves the same design attention as the primary deep-linked experience, rather than defaulting to a generic web page with no relationship to what the link was actually about — routing the fallback to a page that at minimum explains what the link was for and offers an app store link, ideally preserving the same content or context the deep link itself would have shown, gives a user without the app installed a coherent experience rather than a dead end.
The Bottom Line
Verify every specific requirement of the domain association file explicitly rather than assuming a general implementation covers it, and re-check coverage whenever a new subdomain begins sending links. Test from a genuinely uninstalled state and from the actual external contexts links will arrive from, not only by repeatedly tapping links on the same development device, and design the not-installed fallback as a deliberate experience rather than an afterthought.



