Operate
Troubleshooting
Symptoms, causes and fixes.
Find the symptom, check the cause, apply the fix. Commands for the checks are in
Testing and debugging.
Links do not open the app#
| Symptom | Likely cause | Fix |
|---|
| Android opens the browser although the app is installed | The SHA-256 in the dashboard is your upload key, but the installed app is signed by Play App Signing | Add the Play App Signing certificate (Play Console, App integrity) and every other signing certificate |
Android opens the browser, pm get-app-links shows none or legacy_failure | assetlinks.json lacks the package or fingerprint, or verification has not run | Fix the Android app settings, then adb shell pm verify-app-links --re-verify PACKAGE; reinstall on Android 14 and older |
| The live host is not verified on Android 11 and older, but the test host works (or the reverse) | Those versions verify all autoVerify hosts of an app together | Add every certificate to both environments, or declare the test host only in the debug manifest |
| iOS opens Safari or the App Store although the app is installed | Wrong Apple Team ID or bundle ID in the project, or the entitlement does not list the host | Correct the iOS app settings; check applinks:HOST in the built app |
| iOS ignores a correct association file | Apple's CDN still has an old or missing copy | Wait (up to about a day) and reinstall the app; use ?mode=developer for development builds |
| The link only works when long-pressed, or never from Safari | The link was typed into Safari's address bar, or the user chose "Open in Safari" once | Tap it from Notes or Messages; long-press and choose Open in App |
| Nothing happens when a link is tapped on the same domain as the page you are on | The platform treats a same-domain tap as navigation inside the site | Open the link from a different domain or from another app |
| The app opens twice, or shows an unknown-route page | Flutter's own deep linking and the SDK both handle the URL | Turn off FlutterDeepLinkingEnabled / flutter_deeplinking_enabled, and filter your own listener with isBeckLinkUri; see Handle links |
| Instagram, Facebook or another in-app browser does not open the app | In-app browsers cannot hand the link to the system | Expected: they show a page with Open in app; set a custom scheme in the app settings for the button |
The link opens the wrong place#
| Symptom | Likely cause | Fix |
|---|
| A status page instead of a redirect | The link is disabled, archived, expired or blocked, or its domain is not active | Enable the link, extend or remove the expiry, check the domain status |
| 404 on a link | Wrong path (paths are case-sensitive), wrong host, or a test link on the live host | Check the exact URL; test links are on {slug}-test… and need pk_test_… |
| The test link works only with the test key, the live link only with the live key | Test and live are separate | Use pk_test_ with test hosts and pk_live_ with live hosts |
The app opens but LinkEvent.params is empty after an install | Pass query parameters to the app is off for the link or template | Turn it on; parameters are stored when the click happens, so use a new click |
| The in-app route is wrong | deep_link_path is not a route your app knows | Fix the link's route; map unknown routes to a safe default in routeLink |
Deferred deep links#
| Symptom | Likely cause | Fix |
|---|
Android: first open is organic | The app was not installed from Google Play (adb install, sideload), or the click was older than the window | Test with a Play internal-testing build; the default window is 7 days |
iOS: first open is organic | The app was released without enablePasteboard: true, the dashboard switch is off, the user did not tap Get the app, or chose Don't Allow Paste | Pass enablePasteboard: true (needs an app release), keep iOS pasteboard matching on, explain the prompt in your onboarding |
| iOS: the link opens the App Store at once, with no landing page | The dashboard switch iOS pasteboard matching is off for this environment | Turn it on in the project settings; test with the right environment (test and live are separate) |
| iOS: no prompt, no match | The pasteboard did not look like a web URL (the SDK reads it only then), or the app is not on its first run | Reinstall and retry; the SDK reads only on the first run |
| The deferred link arrives after the app showed its home screen | getInitialLink() waits at most firstOpenTimeout (3 s) | Handle onLink; raise the timeout up to 30 s if needed |
API and webhooks#
| Symptom | Likely cause | Fix |
|---|
401 invalid_api_key | Wrong, expired or revoked key, or a publishable key on the REST API | Use a secret key of the right environment |
403 insufficient_scope | The key lacks the scope of the endpoint | Create a key with the scope (the endpoint's reference lists it) |
422 validation_failed | A field is invalid | Read errors[]: each entry has a JSON Pointer and a code |
429 rate_limited | Too many requests | Wait Retry-After seconds, then retry; send fewer, larger requests |
409 idempotency_key_in_progress / 422 idempotency_key_reused | A retry too early, or a key reused with a different body | Wait and retry with the same key; use a new key for a new request |
| Webhook signature does not match | The body was parsed before verifying, or the wrong secret | Verify the raw body with the endpoint's whsec_… secret; see Webhooks |
Webhook endpoint is auto_disabled | It failed for 3 days | Fix the endpoint, then set the status to active |
Item links and previews#
| Symptom | Likely cause | Fix |
|---|
| A generic card for every item | No metadata API, it is disabled, or it fails; a credential cannot be read | Use Test in the metadata API form with a real id |
| An old title after the item changed | The cache has not expired and nobody invalidated, or the chat app keeps its own copy | Call invalidate; use the platform's debugger |
| 404 on a path that looks right | The id does not fit the template's id format, or the template is disabled or archived | Test a URL in Resources shows why |
| The image is missing in the card | The image URL is not https, or its host is not in the allowed list | Add the host to the allowed image hosts |
| Desktop visitors lose the referral | The web URL has no {query} | End the template's web URL with {query} and turn on pass-through |