AASA file served with the wrong content type

Serving apple-app-site-association as HTML, octet-stream or pkcs7 can stop iOS reading it. How to check the content type with curl and serve plain JSON.

SymptomThe AASA file loads in a browser but Apple's CDN copy is empty, stale or reported as unparseable.
Likely causeThe server sends the file as something other than JSON, such as an HTML page, a download, or a signed pkcs7 file.
FixServe the extensionless file as plain JSON with Content-Type application/json and check the CDN copy.

Short answer: Apple's archived documentation says that from iOS 9 the file "may be a JSON file with a MIME type of application/json". Servers often send an extensionless file as application/octet-stream, or return an HTML page instead. Set Content-Type: application/json on the file and confirm the body is plain JSON.

What is happening

AASA content type: the Content-Type header your server sends with the apple-app-site-association file, which should be application/json for an unsigned JSON file.

Because the file has no extension, many servers guess the type. Apple's current pages do not state a required content type; the application/json guidance comes from Apple's archived Handoff guide. Apple's own CDN returns Content-Type: application/json for the files it caches, which is a good sign of what it expects.

  • iOS 8 used signed files with application/pkcs7-mime. Unsigned JSON has been accepted since iOS 9.
  • Whether text/plain or application/octet-stream is rejected today is not documented, so the safe choice is application/json.

Why does this happen?

Static hosts map types by file extension, and this file has none. Frameworks that route unknown paths to an app shell can also return HTML for the URL.

  • Extensionless default: application/octet-stream or text/plain.
  • Single-page app fallback: the server returns index.html for /.well-known/....
  • Old signed file: a CMS-signed file left over from iOS 8 days, sent as application/pkcs7-mime.

How to confirm it

  1. Run curl -I https://example.com/.well-known/apple-app-site-association and read the Content-Type header.
  2. Run curl -s on the same URL and check the body starts with {, not <!DOCTYPE html>.
  3. Optionally, check Apple's CDN copy with curl -i https://app-site-association.cdn-apple.com/a/v1/example.com. This URL is not documented by Apple but is widely used for debugging.
  4. Run the body through a JSON parser such as jq, then sudo swcutil verify on a Mac, to rule out JSON or structure errors.

How to fix it

  1. Set Content-Type: application/json for /.well-known/apple-app-site-association.
  2. Exclude /.well-known/ from any single-page app fallback route.
  3. Replace any signed file with plain, unsigned JSON.
  4. Keep the file name without an extension.
  5. Reinstall the app on a test device to fetch the new copy.

Examples for common hosts:

# Netlify (_headers)
/.well-known/apple-app-site-association
  Content-Type: application/json

# Apache (.htaccess in /.well-known/)
<Files "apple-app-site-association">
  ForceType application/json
</Files>

Android has a firm rule here: Google requires application/json for assetlinks.json, covered in assetlinks redirect and content type. For a full delivery check, see AASA redirect or blocked and the universal links setup guide.

FAQ

Common questions

Does Apple require application/json?

Apple's archived Handoff guide says the file may be JSON served as `application/json` from iOS 9. Current Apple pages are silent on content type, so `application/json` is the safest value.

Can I name the file apple-app-site-association.json to get the right type?

Apple requires the file name without an extension at `/.well-known/apple-app-site-association`. You can keep a `.json` copy if you like, but the extensionless URL is the one iOS uses.

Do I need to sign the file?

No, not for iOS 9 and later. Apple's archived guide says unsigned JSON is fine, and signing was only required for iOS 8.

What if my host cannot set headers on extensionless files?

Use a rewrite or a small function that serves the file with the right header, or a host that supports custom headers. Deep linking providers can also host the file on a branded link domain.

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.