Universal Link and App Link Error Codes, Explained
SWCERR00101, SWCERR00301, legacy_failure, 1026: what each Universal Link and Android App Link error actually means, where you see it, and the fix that makes the app open again. Or let Appy’s free validator find the problem for you in seconds.
First, make sure it is really broken
A lot of “Universal Links don’t work” reports are links behaving exactly as Apple designed them. Apple’s technote TN3155 lists the cases where the app is supposed to stay closed: a URL typed or pasted into Safari’s address bar is direct navigation, so the browser keeps it. A link to the same domain as the page you are on also stays in the browser. And third-party browsers, including the ones inside other apps, decide for themselves whether to hand a link to your app.
So test the honest way before you change a single file. Paste the link into Notes on the iPhone and long-press it. If the setup is right, the menu offers to open it in your app as well as in the browser. Whatever the user picks there becomes the default for that domain, which is another quiet reason a link that worked yesterday opens Safari today.
If Notes offers no app option, something is wrong with the association, and the error code tells you what.
The shortcut: Appy’s free validator
Before you open a terminal, paste your domain into Appy’s Universal Link validator. It fetches your apple-app-site-association file from your own server and from Apple’s CDN separately, so you see at once whether Apple has the same file you do. It also asks Google’s Digital Asset Links API what Android reads from your assetlinks.json. Free, no sign-up, one result page you can send to your developers.
If the files themselves are the problem, Appy’s AASA and assetlinks.json generator writes both from your Team ID, bundle ID and SHA-256 fingerprint. The rest of this guide explains each error, so you know exactly what to fix when the validator flags one.
Ask Apple’s CDN what it has
Since iOS 14, phones never fetch your apple-app-site-association file from your server. They get it from Apple’s CDN, which fetches it from you. So the first question is not “is my file right?” but “what does Apple have?”.
What Apple’s CDN holds for your domain
curl -sD - "https://app-site-association.cdn-apple.com/a/v1/links.example.com" -o /dev/nullA failing domain answers like this
HTTP/1.1 404 Not Found
Apple-Failure-Reason: SWCERR00101 Bad HTTP Response: 404 Not Found
Cache-Control: max-age=3600,publicYour own server, as the CDN sees it
curl -v -A "AASA-Bot/1.0" https://links.example.com/.well-known/apple-app-site-associationThe SWCERR codes and what fixes them
Apple doesn’t publish a list of these codes. The ones below are the messages Apple’s CDN returns in the Apple-Failure-Reason header, each confirmed in Apple Developer Forums threads or in our own requests to the CDN.
SWCERR00101 · Bad HTTP Response: 404 Not Found
The CDN asked for your file and got something other than a 200. Most often the file sits on the root domain while the entitlement names a subdomain, or the other way round. Each host in applinks: needs its own file at https://that-host/.well-known/apple-app-site-association. A 502 here means your origin was down when Apple asked.
SWCERR00201 · Insecure (non-https) redirects forbidden
The file’s URL redirects to an http:// address. Serve it directly over HTTPS on every domain. Apple’s docs say no redirects at all; in our tests the CDN followed an https-to-https redirect, but a downgrade to http always fails.
SWCERR00202 · Connections to private/reserved IP addresses are not allowed
The hostname resolves to a private or reserved address, so Apple won’t connect. Typical on staging domains that only exist inside a VPN. Use developer mode for those (more below) and a public host for production.
SWCERR00301 · Timeout
Apple’s fetcher waited and got no headers back. Firewalls, geo-blocking and bot protection that challenge unknown clients are the usual cause. Apple says the file must be reachable from every IP and doesn’t publish its ranges, so allow the path for everyone.
SWCERR00302 · Network error (temporary)
A temporary failure, often DNS. If your DNS is healthy it usually clears on the next fetch, which for a failure is within the hour.
SWCERR00303 · TLS error
The certificate is expired, issued for a different host, self-signed, or the handshake failed. Apple needs a publicly trusted certificate that covers the exact hostname. A certificate for example.com does not cover links.example.com unless it says so.
SWCERR00305 · Network error
The CDN connected but the transfer broke: EOF, connection refused, or gzip: invalid header when the server claims compression it doesn’t send. Check the WAF and compression settings for that one path.
SWCERR00401 · Bad JSON content
The CDN got something that isn’t JSON, typically an HTML challenge page or a login page. The detail “invalid character ‘<’” gives it away. An Apple engineer’s fix in the forums: make the server return the raw file to any user agent, including AASA-Bot/*.
Check the paths with swcutil
Once Apple has the file, the next question is whether your link matches it. On a Mac, swcutil tests a local copy of the file against a real URL, which is the check Apple’s engineers recommend over developer mode.
Download test
sudo swcutil dl -d links.example.comMatch test
sudo swcutil verify -d links.example.com -j ./apple-app-site-association -u https://links.example.com/promoWhat a match looks like
{ s = applinks, a = ABCD123.com.example.app, d = links.example.com }:
Pattern "https://links.example.com/promo" matched.What the phone itself thinks
With Developer Mode on, Settings › Developer › Universal Links has a Diagnostics screen: type a full URL and it tells you whether an installed app claims it. For the full story, take a sysdiagnose and open swcutil_show.txt. Search for your app ID and read three lines.
Site/Fmwk Approval should say approved. Unspecified or denied means the phone never received an approved file for that app and domain: check the entitlement, public access and the Team ID prefix. User Approval shows whether the person chose the browser for this domain. Last Checked and Next Check show when Apple last fetched your file.
That last point explains most “I fixed it but nothing changed” moments. After install, a phone checks the file roughly once a week. To test a fix now, reinstall the app. For staging, add ?mode=developer to the applinks entry: it skips the CDN, but only for development-signed builds on devices where you have opted in.
The numbers worth remembering
- how long Apple’s CDN kept a good file in our tests
- 6 h
- how long it kept a failure
- 1 h
- how often an iPhone rechecks after install
- ~1 week
- Android’s minimum wait before you check verification
- 20 s
how long Apple’s CDN kept a good file in our tests
how long it kept a failure
how often an iPhone rechecks after install
Android’s minimum wait before you check verification
Android App Links: the states pm get-app-links reports
Android has no CDN in the middle. The device’s verifier fetches https://your-host/.well-known/assetlinks.json itself, and since Android 12 an unverified link no longer shows a chooser: it simply opens in the browser. That is why a missing fingerprint looks exactly like “the link works, just not in my app”.
Android 12 also changed how several hosts are judged. Each host is now verified on its own; on Android 11 and lower, one host that fails verification fails all of them. And on Android 15, a change to assetlinks.json can take up to seven days to reach every device.
Re-run verification from your laptop
Reset, verify, read
adb shell pm set-app-links --package com.example.app 0 all
adb shell pm verify-app-links --re-verify com.example.app
adb shell pm get-app-links com.example.appTypical output
example.com: verified
sub.example.com: legacy_failure
example.org: 1026What each state means
verified
The domain passed. If links still open the browser, look at the intent filter: android:autoVerify="true", the BROWSABLE category, and both http and https schemes.
none
Nothing recorded yet. Wait a few minutes and run verify-app-links again.
legacy_failure
The legacy verifier rejected the domain without saying why. Start with the file itself: HTTP 200, application/json, HTTPS, no redirects.
1024 and higher (for example 1026)
A verifier-specific error. Android’s docs point at the network and the hosting: the same 200, JSON, HTTPS and no-redirect rules.
approved / denied
Forced by a shell command, not by verification. Reset with set-app-links before you trust any result.
migrated / restored / system_configured
Carried over from legacy verification, restored with user data, or set by the device configuration. Not errors, but not proof that your file works today either.
The fingerprint that is right on your laptop and wrong in the Play Store
The most common Android failure has nothing to do with hosting. With Play App Signing, Google re-signs your app with its own app signing key. The SHA-256 you get from keytool on your upload key is not the one on users’ phones, so a release build fails while your local build passes.
Copy the fingerprint from Play Console › Release › Setup › App signing instead. The sha256_cert_fingerprints array takes several values, so keep your debug key there too, in uppercase. And remember that a redirect from example.com to www.example.com, or from http to https, means Android verifies none of your links.
See what Google reads from your file
Digital Asset Links API
curl "https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls"Keep your campaigns running while you fix it
Broken association files shouldn’t cost you installs. An Appy link sends every phone to the right store on every plan, Huawei AppGallery included, and on Pro it tries your app first, so people who already have it land inside it. No AASA file, no SDK, no app release. When your Universal Links work again, keep the same Appy link: printed codes and posts don’t change.
appy.to/yourapp
works while you debug
- iPhoneYour app on Pro, or the App Store
- AndroidYour app on Pro, or Google Play
- HuaweiAppGallery
- ComputerYour website
Read next
- Universal Link validatorChecks your AASA on your server and on Apple’s CDN, plus assetlinks.json, in one go.
- AASA and assetlinks.json generatorWrites both files from your Team ID, bundle ID and SHA-256.
- Universal Links open Safari instead of the appThe behaviour-level causes, from the same-domain rule to user choice.
- Android App Links verification failedA deeper walk through the Android side.
Error code questions
Where do I see SWCERR codes?
In the Apple-Failure-Reason header when you request https://app-site-association.cdn-apple.com/a/v1/your-domain, in swcutil dl output on a Mac, and in the swcd log on a device.
Is there a tool that checks all of this at once?
Yes. Appy’s Universal Link validator is free and needs no sign-up. It checks your AASA file on your server and on Apple’s CDN, and your assetlinks.json through Google’s Digital Asset Links API, then tells you what to fix.
How do I make Apple pick up my fixed AASA file?
You can’t purge Apple’s CDN. It refetches when its cache expires, which was one hour for failures in our tests. Then reinstall the app on your test phone so it fetches the new copy instead of waiting for the weekly check.
Is the apple-app-site-association file size limited?
Apple documented a 128 KB limit in 2016. Current docs don’t repeat it, but keeping the file small avoids the question.
Why does my link open the browser when I type it into Safari?
That is expected. Typed URLs and links within the same domain stay in the browser by design. Test from Notes or Messages instead.
What does legacy_failure mean on Android?
The legacy verifier rejected the domain and Android doesn’t say why. Check that assetlinks.json returns 200 as application/json over HTTPS with no redirects, and that it lists the Play App Signing fingerprint.
Can I avoid all of this?
Partly. On the Pro plan, an Appy link tries your app’s URL scheme first and falls back to the right store, so it works without AASA files on your own domain. Real Universal Links still need the setup above.
Continue exploring
Android App Links Not Verified: A Five-Minute Diagnosis with adb
Since Android 12, an App Link that fails domain verification opens in the browser instead of your app — silently, and not on every device. The adb checklist that finds the cause fast, including the Play signing key mismatch behind most incidents.
Universal Links Open Safari? Fix AASA, App Links, Redirects, and Headers
A practical troubleshooting workflow to fix universal links and app links that open the browser instead of your app.
How In-App Browsers Handle Deep Links: Instagram, TikTok, Facebook, Gmail, Telegram and More
Why a link that opens your app from Safari dies inside Instagram: the three kinds of in-app browser, the iOS and Android rules, and what each app documents, from Facebook to Telegram.
Looking for something else? Browse all topics on the blog.
Stop losing taps to broken links
Find the broken file with the free validator, and keep every campaign working in the meantime with an Appy link: the right store on every plan, your app on Pro.