Skip to content

Troubleshooting

Start with the path that is failing: operating-system routing, SDK delivery, deferred matching, or event attribution.

Check that:

  1. Ferry.configure runs before link handling.
  2. The app registers the Ferry link listener early in startup.
  3. The configured key starts with pk_ and belongs to the same project as the hostname.
  4. The app forwards the initial link and later foreground links as shown in its platform guide.
  5. The link contains a valid Ferry hostname and slug.

Enable SDK debug logging during development to confirm configuration and lifecycle decisions. Ferry redacts keys and payloads from its diagnostics.

iOS opens Safari

The most common causes are:

  • The Associated Domains capability is missing from the signed app.
  • The hostname is missing its applinks: entry.
  • The project’s Apple team ID or bundle ID does not match the installed app.
  • The device cached an older Apple App Site Association file.
  • The user previously chose to open this domain in Safari.

Verify the entitlement in the built app, not only in the Xcode project. After changing the association file or entitlement, delete and reinstall the app to refresh the device cache.

Universal Links should be tested by tapping a link from Messages, Notes, or another app. Typing or pasting a URL directly into Safari’s address bar is not an equivalent test.

Android shows an app picker

Check that:

  • The intent filter has android:autoVerify="true".
  • The scheme is https and the host exactly matches the Ferry domain.
  • The project package name matches the installed app.
  • The project’s SHA-256 signing certificate fingerprint matches the build being tested.
  • Debug and release signing fingerprints are both configured when both builds need verification.
  • The activity receives initial and onNewIntent deliveries.

Android verification can remain stale after manifest or association changes. Reinstall the app, then recheck the domain association from Android’s app settings.

Direct and deferred delivery use different platform handoffs. Check:

  • Android: Install through the Play Store path so Play Install Referrer can participate. In-app browsers may strip or isolate the handoff.
  • iOS: App Clip or pasteboard signals may be unavailable, leaving only probabilistic matching.
  • The user opened the app within the configured matching window.
  • The first link listener was registered so the SDK started matching.
  • A previous definitive attributed or organic result did not already resolve the installation.

Ferry intentionally returns no match when fingerprint candidates are ambiguous, which is common on shared networks and popular device profiles.

The payload is missing a value

Confirm whether the link is a normal link or a template. Template query values are merged only when the link is opened, and all payload values are strings.

Also check that:

  • The key is not one of Ferry’s reserved internal parameters.
  • The app reads from link.data, not from the full URL.
  • The current app version recognizes the route and key.
  • The link creator stored the value in the payload rather than only in campaign metadata.

Events appear without attribution

The event can be valid even when no installation match was available. Confirm that:

  • The link listener ran before the event was tracked.
  • The installation received an attributed result.
  • The event occurred within the SDK’s recent link-attribution window.
  • A reinstall did not intentionally clear the previous installed-app attribution.

A purchase is rejected

Check that:

  • The transaction ID is non-empty and unique in the project.
  • The value is positive and finite.
  • The currency is a three-letter code.
  • The currency matches the project’s reporting currency exactly.
  • The optional product ID is an opaque identifier, not customer data.

Register the SDK’s event-delivery listener to read the rejection reason. One rejected purchase does not invalidate accepted sibling events.

Common causes:

  • Client-side link creation is disabled for the project.
  • The hostname is not active or belongs to another project.
  • The installation reached the hourly or daily rate limit.
  • The payload contains non-string values.

Respect the returned retry interval for rate limiting. Do not retry a disabled-project response.

Still blocked?

When contacting Ferry support, include:

  • Platform, operating-system version, and SDK version.
  • Whether the app was installed before the link was opened.
  • Shared or custom hostname, without the full payload or query string.
  • Debug or release build.
  • The safe SDK diagnostic messages around the attempt.

Do not send a public or secret key, installation ID, customer ID, transaction ID, click ID, or full link payload.