assetlinks.json is not valid JSON

A syntax error in assetlinks.json leaves Android with no statements, so App Links fail verification. How to find the error, fix it and re-verify with adb.

SymptomAndroid App Links open the browser or a chooser, and pm get-app-links does not show verified for the domain.
Likely causeThe assetlinks.json file has a syntax error, so Android reads it as an empty statement list.
FixFix the syntax error, serve the file with a 200 as application/json, then re-run verification with adb.

Short answer: If assetlinks.json cannot be parsed, Android has no statements for your domain and App Link verification fails. On Android 11 and lower that can stop every host in the app from verifying. Run the file through a JSON parser such as jq to find the line, fix it and re-verify with adb.

What is happening

Invalid assetlinks.json: a Digital Asset Links file that a JSON parser rejects, which leaves Android with an empty statement list for that host.

Google's statement list documentation says any response other than a 200 is treated as an error and results in an empty statement list. A file that cannot be parsed has the same outcome: no statement links the site to your app.

  • Links open in the browser instead of the app.
  • adb shell pm get-app-links shows a state other than verified.
  • On Android 11 and lower, Google says "verification fails if even one host cannot be verified", so one broken file can affect all hosts.

Why does this happen?

The file is usually hand-edited or assembled from a snippet. JSON rejects trailing commas, comments, single quotes and curly quotes.

  • Trailing comma after the last fingerprint or the last statement.
  • Two snippets pasted together without merging them into one array.
  • Smart quotes from a document or chat tool.
  • HTML instead of JSON returned by a framework route or error page.

How to confirm it

  1. Fetch the file: curl -i https://example.com/.well-known/assetlinks.json. Check for a 200, Content-Type: application/json and a body starting with [.
  2. Run the body through a JSON parser, for example curl -s https://example.com/.well-known/assetlinks.json | jq ., which reports the line and column of any syntax error. Google's Statement List tester also reports a file it cannot read.
  3. Ask Google's Digital Asset Links API what it can read: https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls. An empty list means no usable statements.
  4. On a device, run adb shell pm get-app-links com.example.app and check the domain state.

How to fix it

  1. Correct the syntax error and validate again.
  2. If you merged several snippets, make sure the result is one array of statement objects.
  3. Serve the file at https://example.com/.well-known/assetlinks.json with a 200, no redirect and application/json.
  4. Re-run verification on Android 12 and later:
  • adb shell pm set-app-links --package com.example.app 0 all
  • adb shell pm verify-app-links --re-verify com.example.app
  • wait a few minutes, then adb shell pm get-app-links com.example.app
[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

The Android App Links setup guide has a valid example to start from. Next, check the fingerprint, which is the most common problem once the JSON parses.

FAQ

Common questions

What does Android do with an unreadable assetlinks.json?

It ends up with no statements for that host, so verification fails. The app is not set as the default handler for links on that domain.

Can one bad file break App Links on other domains?

On Android 11 and lower, yes, because the app is only verified if every host in the manifest verifies. On Android 12 and later, each host is verified separately.

How do I check the file the way Google sees it?

Call the Digital Asset Links API `statements:list` endpoint with your site and the `handle_all_urls` relation. It works without authentication and returns the statements Google can read.

Do I need to reinstall the app after fixing the file?

On Android 14 and lower, Google says updates are usually only picked up on install or update. You can force a re-check on a test device with `pm verify-app-links --re-verify`.

What are UTM parameters?

UTM parameters are tags added to the end of a link, such as utm_source and utm_campaign, that tell analytics tools where a visit came from. They let you see which campaign, channel and ad brought each visitor.

Which UTM parameters are required?

Use utm_source, utm_medium and utm_campaign on every campaign link. utm_term and utm_content are optional and help you compare keywords or ad variants.