Troubleshooting
When a link opens the browser or store instead of your app — domain verification, signing fingerprints, caches, consent, and the checks that find the cause.
Golden rule: a link that opens the browser or store instead of your installed app is almost always domain verification (AASA / assetlinks.json) — usually a signing-fingerprint mismatch or a stale cache, not SDK code. Apple documents the association-file format under supporting associated domains; Google documents the Android side under verifying App Links.
Check the files before you read further. Our free Universal Links & App Links validator fetches the AASA and assetlinks.json for any domain and flags the failures that don't show up in a browser — a wrong Content-Type, a redirect in front of the file, a missing fingerprint. No signup, and it works on any domain, not just ours.
Quick hits
- Address-bar navigation never opens the app — by design on both platforms. Test by tapping a link from another app, or: adb shell am start -a android.intent.action.VIEW -d "https://…".
- Android has two caches — Google's Digital Asset Links crawl (~1 h) and the per-device verdict set at install time. Fix assetlinks → wait for Google → reinstall or adb shell pm verify-app-links --re-verify <package>.
- Deferred link never arrives — SDK not configured, bad API key, or it wasn't a genuine first launch. Re-test: uninstall → click link → reinstall → launch.
- Links route but nothing attributes — that's the consent gate doing its job (on by default on iOS and Android). Call setConsent(true) after your consent prompt; until then installs are recorded without attribution and events are queued.
- Deferred links work but re-engagement doesn't — you set linkDomains and the host isn't listed. Re-engagement opens only route for listed hosts; deferred links skip the check, which is why fresh installs looked fine. Add the host or clear linkDomains.
- Deferred installs on iOS arrive unattributed — clickTokenSource defaults to .pasteButton, so the click token is read only when the user taps a paste control. Render LinkTrailPasteButton (or a UIPasteControl natively) and set autoTrackInstall: false, or switch to .automatic and accept the Allow Paste alert. Android is unaffected: it uses the Play Install Referrer.
- An invalid API key does NOT fail configure — the backend rejects it asynchronously (401) and it surfaces via onError as invalidAPIKey / invalid_api_key. Watch onError during integration.
- React Native on iOS: links never arrive at all — your AppDelegate isn't forwarding to RCTLinkingManager. The continue-userActivity override for Universal Links is not in the stock RN template; see the React Native SDK page.
- Wrong screen — your router doesn't handle that deep link path; log the link in onLink.
Enable SDK logs to see matching and routing decisions — Android: LinkTrailOptions(logEnabled = true), then adb logcat -s LinkTrail. (With no API key configured the SDK never initializes, so the log filter shows nothing at all.)
Faster deferred re-testing: instead of uninstall/reinstall, call resetForTesting — LinkTrail.resetForTesting() on iOS and React Native, LinkTrail.resetForTesting(context) on Android. It clears the install flag, cached attribution, and device ID so the next launch behaves like a genuine first launch. Testing only — never ship it.