ZipQuantum Engineering ·

Deep Link Doctor: A Universal Link and Android App Link Tester

Diagnose silent Universal Link and Android App Link failures across AASA, assetlinks.json, redirects, HTTPS, identifiers, certificates, and path rules.

A valid-looking link can still miss the app

A Universal Link or Android App Link can look completely normal in a browser, return a successful page, and still fail to open the installed app. That is what makes deep-link failures expensive: the fallback often hides the defect.

The user sees a web page instead of the intended product, invitation, checkout, or account screen. Marketing may record the click. QA may report that “the URL works.” Yet the app handoff never happened.

The cause is usually not the URL alone. Verified app links depend on a chain of public files, transport rules, identifiers, certificates, path patterns, and app-side configuration. A single mismatch can turn a direct app journey into a silent browser fallback.

The diagnostic principle: test the public delivery chain first, then verify the app and device state. Do not debug routing code while the domain association is already broken.

1. Map the silent failure chain before changing code

Think of the app-opening decision as a sequence. The public URL must be reachable over HTTPS. The operating system must retrieve the correct association file directly. That file must be valid, identify the installed app, and cover the requested path. The app must also declare the corresponding domain and handle the incoming route.

1. Public URLReachable over HTTPS with the expected host and path
2. Association fileAASA or assetlinks.json served directly from the domain
3. Identity matchApp ID, package name, and certificate match the release
4. Route matchThe requested path is included and the app handles it

A useful deep link checker should therefore do more than confirm that a JSON file exists. It should tell you which layer failed and what to repair first.

Wrong locationThe association file is missing from the expected well-known endpoint.
Redirected fileA CDN, locale rule, or security plugin redirects a request the platform expects directly.
Wrong MIME typeThe server returns HTML or a generic download type instead of the expected JSON response.
Identity mismatchThe deployed file describes a different App ID, package, or signing certificate.
Path gapThe file is valid, but the campaign route is outside the declared coverage.
Stale device stateThe server is fixed, but the device has not refreshed its association decision yet.

If you need a broader view of how iOS and Android verification models differ, start with Universal Links vs Android App Links. The rest of this guide focuses on diagnosing a concrete failure.

2. What an AASA validator needs to check

Apple Universal Links rely on an apple-app-site-association file, commonly called AASA. It is normally published at:

https://example.com/.well-known/apple-app-site-association

The file has no .json extension. A practical AASA validator should inspect at least five things:

  1. HTTP status: the endpoint returns the file successfully.
  2. No redirect: the request is served directly rather than forwarded through another URL.
  3. Content-Type: the response is served as valid JSON content, or a supported signed association payload where relevant.
  4. Structure and App ID: the applinks object is valid and includes the expected application identifier.
  5. Path or component coverage: the URL you are testing is allowed by the declared paths or components rules.

The App ID combines an Apple application identifier prefix with the bundle identifier. A file can be syntactically perfect and still point to the wrong build. This often happens when production, staging, white-label, or transferred apps share deployment infrastructure.

Path matching deserves its own test. Apple supports both legacy paths rules and the newer components model. Inclusion, exclusion, case sensitivity, and rule order can produce results that are not obvious from a quick visual review.

Apple’s documentation requires the association file to be available over HTTPS and describes the App IDs and URL components that a domain delegates to an app. See Supporting associated domains and the current applinks structure.

Android App Links rely on Digital Asset Links served from:

https://example.com/.well-known/assetlinks.json

An Android App Link validator should verify:

  • the endpoint returns HTTP 200 over HTTPS;
  • the response does not depend on a redirect;
  • the response is valid JSON served as application/json;
  • the relation permits URL handling;
  • the declared Android package matches the installed application;
  • the SHA-256 signing-certificate fingerprint matches the certificate used for the distributed build.

The certificate check is where otherwise correct deployments commonly fail. Local debug builds, direct APKs, store-managed signing, and release pipelines may use different certificates. The fingerprint in assetlinks.json must describe the build that users actually install.

Android verifies every hostname declared by the app. A working association on example.com does not automatically cover www.example.com, a campaign subdomain, or a separate short-link domain.

Android documents that the system requests https://hostname/.well-known/assetlinks.json for declared hosts and provides device commands for resetting, re-running, and reading verification state. See Verify App Links.

4. Check HTTPS, redirects, and Content-Type before parsing JSON

Teams often copy an association file into a validator, see valid JSON, and conclude that the setup is correct. That skips the delivery layer—the part the operating system actually sees.

Check Silent failure First repair
HTTPS Invalid, expired, or mismatched certificate; HTTP downgrade Serve the exact host securely with a valid certificate chain
Redirects HTTP-to-HTTPS, www, locale, login, CDN, or trailing-slash redirect Return the association file directly at the required URL
Status 404, 403, 5xx, bot protection, or regional denial Allow public retrieval and return a stable 200 response
Content-Type HTML error page, download response, or generic binary type Configure the correct MIME type at the origin and CDN
Body Invalid JSON, comments, encoding errors, or a cached old file Validate the served response—not only the source file

A redirect that seems harmless to a person can be fatal to association discovery. Likewise, a security layer may return HTTP 200 while serving an HTML challenge page. Always inspect the final response body and headers from outside your internal network.

5. Match the release identity and the exact campaign path

After the file is reachable, compare its declarations with the release configuration—not with a value copied from an old ticket.

For Apple

  • confirm the domain appears in the app’s Associated Domains entitlement;
  • compare the expected App ID with the AASA entry;
  • test the real path against every relevant include and exclude rule;
  • repeat the check for each hostname used by campaigns.

For Android

  • confirm the manifest declares the correct scheme, host, and android:autoVerify="true";
  • compare the production package name with package_name;
  • compare the production SHA-256 fingerprint with every declared fingerprint;
  • test device verification for each declared host.

Path coverage matters because campaigns rarely link only to /. They link to product slugs, invitation tokens, checkout routes, referral paths, or localized pages. Test a representative URL from each route family, including case, encoded characters, and excluded areas.

6. Deep Link Doctor turns the public configuration into a repair queue

Deep Link Doctor is a public diagnostic for Apple Universal Links and Android App Links. The first test does not require an account.

Enter a public domain or URL. If you want exact matching, add the expected Apple App ID, Android package, SHA-256 certificate fingerprint, or path. The diagnostic checks the public delivery chain and groups findings by severity, with a concrete next action attached to each issue.

Enter the URLStart with the public domain or a failing campaign path
Add expectationsOptional App ID, package, fingerprint, and path
Fix in orderResolve critical delivery errors before lower-priority warnings
Claim if usefulKeep and monitor the asset only when ongoing ownership is needed

The public diagnostic reads public HTTP(S) endpoints. It does not need source-code access or developer-account credentials. After the first result, you can choose to claim the asset in a workspace for repeat checks and monitoring.

What it does not prove: a healthy public configuration does not guarantee that every installed build handles the route correctly. App entitlements, manifest filters, navigation code, cached platform state, user preferences, and the link’s source context still need device-level testing.

Use the result in priority order

  1. Fix unreachable hosts, HTTPS problems, redirects, and invalid response bodies.
  2. Fix malformed AASA or assetlinks structures.
  3. Fix App ID, package, and certificate mismatches.
  4. Fix path coverage and exclusions.
  5. Re-run the public diagnostic.
  6. Only then reset platform verification and repeat device tests.

7. Verify the repair where users actually tap

A server-side pass is necessary, not sufficient. Complete the repair with a small state matrix:

  • iOS and Android;
  • current production build and the next release candidate;
  • app installed and not installed;
  • fresh install and previously installed device;
  • email, messaging, browser, QR, and paid-social contexts that matter to the campaign;
  • target path, excluded path, and safe web fallback.

On Android, use the documented pm verify-app-links and pm get-app-links commands when you need the device’s verification state. On iOS, test from a realistic external context and remember that same-domain navigation or user preference can keep a link in Safari even when the association is healthy.

For a campaign-wide checklist that includes install state, fallback, attribution, and ownership, use the Mobile Campaign Link Audit. If your flow must recover intent after an app-store installation, continue with the guide to deferred deep linking without a proprietary SDK.

A repeatable workflow for product teams and agencies

  1. Record the failing URL and context. Note the platform, app version, install state, source app, and expected screen.
  2. Run the public check. Save the result with the deployment or incident record.
  3. Assign each failed layer. DNS/TLS and headers may belong to infrastructure; identifiers to mobile release engineering; path rules to product or web teams.
  4. Deploy one controlled fix. Avoid changing redirects, association files, and app routing simultaneously unless the incident requires it.
  5. Re-run and test devices. Separate “public configuration healthy” from “installed app behavior confirmed.”
  6. Keep an owner. Claim and monitor important domains when ongoing visibility is worth maintaining.

This division is especially useful for agencies: it gives the client’s web, infrastructure, and mobile teams the same evidence without requiring access to each other’s private systems.

Diagnose the public deep-link chain

Start with a domain or failing URL. No account is required for the first test, and the result separates critical failures, errors, warnings, and passing checks.

Frequently asked questions

It should test the public URL, HTTPS delivery, redirects, the AASA endpoint, JSON structure, App IDs, and path or component coverage. A public pass should then be followed by app entitlement and device testing.

It should verify the public assetlinks.json response, relation, package name, signing-certificate fingerprints, and delivery headers. Device verification state still needs to be checked after server-side repairs.

Common causes include a missing or redirected association file, invalid JSON, a wrong Content-Type, App ID or package mismatch, an incorrect certificate fingerprint, uncovered paths, missing app declarations, stale verification state, or a user preference that keeps the link in the browser.

No. The public test reads the public domain, page, and association files needed for diagnosis. It does not require source-code or developer-account access.

Do I need an account to run the first test?

No. You can run the initial public diagnosis without an account. Claiming the asset is optional and is used when you want to keep it in a workspace, repeat checks, and monitor it.

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *