kloudmasterkloudmaster

Technology

22 September 2026

Our iOS Deep Link Looked Correct — Until AWS Amplify Returned a 301

iOS Universal Links can fail even when the app configuration looks correct. In this case, an AWS Amplify redirect on Apple’s extensionless association file quietly broke the trust chain. Here’s how I diagnosed and fixed it.
Deep linking sounds straightforward until several platforms have to agree on the same URL.

A user taps an HTTPS link. The operating system recognises the domain. The native app opens. The user lands on the right screen.

At least, that is how it is supposed to work.

Recently, I worked on the infrastructure side of an iOS Universal Links implementation where the configuration initially looked correct. The required association file existed. The domain was live over HTTPS. The mobile team knew which domain needed to be associated with the app.

But the link still was not behaving the way we expected.

The issue turned out not to be in the mobile application's routing logic.

It was an HTTP redirect.

More specifically, it was the way AWS Amplify handled an extensionless path that Apple expects to be served exactly as requested.

That small difference between “the file exists” and “the file is served exactly the way Apple expects” was the real problem.

What iOS Universal Links actually depend on

Universal Links allow a normal HTTPS URL to open a native iOS application instead of Safari.

For that to work, iOS needs to establish trust between two sides: the website and the application.

On the website side, the domain hosts an apple-app-site-association file, commonly called the AASA file.

On the application side, the app declares the same domain using Apple’s Associated Domains entitlement.

Those two sides must agree.

If the website does not correctly identify the application, the association fails. If the application does not declare the domain correctly, the association fails.

And if the AASA file is not delivered correctly over HTTP, the association can fail even when the contents of the file are perfectly valid.

In this case, my responsibility was the website and infrastructure side: make sure the association file was available from the expected location and returned correctly. The mobile team would handle the application entitlement and routing logic inside the app.

The infrastructure requirement sounded simple.

Apple expects the file at a path similar to:

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

Notice something unusual about that URL.

There is no .json extension.

That detail became important very quickly.

The first clue was not inside the JSON

The association file itself was not the first thing I needed to debug.

The HTTP response was.

Instead of immediately looking at the contents of the file, I checked what the server was actually returning.

I used curl to inspect three things:

The HTTP status code.

The number of redirects.

The Content-Type.

For this endpoint, the result I wanted was effectively:

status=200 redirects=0 content-type=application/json

Those three values matter.

The file should return HTTP 200.

The response should be JSON.

And critically, there should be no redirect.

But the server was not giving me that clean response.

The extensionless path was redirecting.

That was the real clue.

AWS Amplify saw a directory where Apple expected a file

The application frontend was hosted using AWS Amplify.

Amplify was perfectly happy serving normal files such as:

assetlinks.json

That file has an extension.

The Apple association file was different.

Apple expects:

apple-app-site-association

with no .json suffix in the public URL.

In this environment, Amplify treated that extensionless request more like a directory-style path.

The request received a redirect to a path with a trailing slash. From there, it could fall through to the application’s normal single-page application routing behaviour and eventually return the wrong response.

So the request effectively behaved like this:

/.well-known/apple-app-site-association

301 Redirect

/.well-known/apple-app-site-association/

Wrong response

The file existed.

The JSON could be correct.

HTTPS could be valid.

And the implementation could still fail because the request itself was not being served in the format expected by Apple.

That was the part I found most interesting.

The bug was not really:

“The AASA file is missing.”

It was:

“The hosting platform and Apple disagree about how this path should behave.”

The workaround: keep Apple’s URL, change how Amplify serves it

The solution required separating the public URL from the physical file that Amplify served internally.

Apple still needed to request:

/.well-known/apple-app-site-association

But Amplify was much happier serving:

/.well-known/apple-app-site-association.json

So I kept both ideas.

A .json version of the association file was included in the frontend’s public assets.

Then I added an Amplify rewrite rule so that the Apple-required extensionless URL internally resolved to the JSON file.

Conceptually, the rule was:

Source:

/.well-known/apple-app-site-association

Target:

/.well-known/apple-app-site-association.json

Status:

200

This distinction mattered.

The browser or Apple service still requested the extensionless path.

There was no visible redirect.

Amplify internally served the JSON file.

And the client received HTTP 200.

That preserved Apple’s expected public URL while working around the hosting platform’s behaviour.

The rewrite rule order mattered too

There was another small detail that could easily have turned this into a second debugging session.

The frontend was a single-page application.

Like many SPAs, it already had a catch-all rule similar to:

/<*> → /index.html

That rule exists so client-side routes still load the application.

But a catch-all is exactly what the name suggests.

It catches everything.

If the SPA rule runs before the AASA-specific rule, the special association-file request can be swallowed by the frontend routing behaviour.

So the order had to be:

First: the AASA-specific rewrite.

Second: the SPA catch-all.

Not the other way around.

This is one of those infrastructure details that looks trivial after you solve it.

During troubleshooting, however, it can be the difference between a working Universal Link and several more hours of investigating the mobile app.

Verification mattered more than the deployment result

Once the rewrite was deployed, I did not treat a successful deployment as proof that the problem was solved.

I went back to the HTTP response.

The important result was:

status=200 redirects=0 content-type=application/json

That gave me much more confidence than a green deployment pipeline.

It told me what an external client actually saw.

I also inspected the returned content separately to make sure the association file was being served as expected.

At that point, the infrastructure side was complete.

The remaining work belonged to the mobile application.

Knowing where DevOps responsibility ends

This incident was also a useful reminder that deep linking is a cross-team feature.

The infrastructure team can make the domain correct.

That does not automatically make the application respond to the link.

From the DevOps side, my responsibilities were primarily to make the association file reachable over HTTPS, ensure the endpoint returned the correct content, remove the redirect, make sure the hosting platform did not send the request through the SPA fallback, and verify the public endpoint externally.

The mobile team then needed to configure the Associated Domains entitlement and handle the incoming URL in the application’s routing layer.

That separation is useful during incidents because it gives everyone a clear diagnostic boundary.

If curl returns a 301, I still have an infrastructure problem.

If curl returns 200, zero redirects, and application/json, and the association file contains the expected application identifiers, then the investigation can move further into the mobile configuration and routing behaviour.

What this incident reinforced for me

The main lesson was not simply that AWS Amplify needed a rewrite rule.

It was that platform integrations often depend on details below the application layer.

A file existing in a deployment artifact does not guarantee that an external platform receives it correctly.

A valid JSON document does not guarantee that the URL serving it behaves correctly.

A successful frontend deployment does not prove that a standards-sensitive endpoint returns the required HTTP semantics.

And when several systems are involved, each one can be individually “working” while the integration between them is still broken.

In this case, Apple’s Universal Links expected an extensionless endpoint. Amplify treated that extensionless path differently from a normal JSON file. SPA routing introduced another layer capable of intercepting the request. A small rewrite rule reconciled those behaviours.

The code change itself was small.

Understanding why it was necessary was the real engineering work.

The debugging pattern I would use next time

The next time I troubleshoot Universal Links or another platform-verification endpoint, I will not begin by assuming the JSON is wrong.

I will start one layer lower.

What HTTP status code is actually returned?

Was there a redirect?

What is the Content-Type?

What does the external URL return without browser assumptions?

Is a reverse proxy, CDN, hosting platform, or SPA rewrite modifying the request?

Only after those questions are answered would I move further into the application configuration.

Because sometimes the most useful debugging tool is not Xcode, Flutter, or even the AWS console.

Sometimes it is just:

curl

And one unexpected 301 tells you almost everything you need to know.
210
Feedcover logoFeedcover logo
Newsletter
Notifications
All caught up
Sign in to see notifications.
Menu
Support

Watch videos, read African stories, ask questions and discover creators.

CompanyBrandCreatorsReferralWalletTermsPrivacy

Explore

For YouFeedsQuestionsCollectionsNewslettersCreatorsCategoriesTags
Get it on Google PlayDownload on the App Store
iwilltrainupachildiwilltrainupachild
Parenting5 Oct 2026

🎙️ Episode 076 | The Importance of Teaching Children to Pray | Train up a Child Parenting Podcast

Remember, our goal is not merely to raise children who know how to recite prayers, but children who know how to seek God.
204
kawgo12345kawgo12345
Services7 Oct 2026

DON'T FORGET ADULT BIRTHDAYS



170
temmytemmy
Food30 Jul 2026

📍 Weekend Hangout Spots In Lagos

Four Places Worth Checking Out This Weekend

Looking for somewhere different to spend your weekend? From a brand-new restaurant that's already drawing crowds to a self-serve ice cream spot perfect for dessert lovers, here are four places making waves this week.
570
kawgo12345kawgo12345
Services5 Oct 2026

BIRTHDAYS AND YOUNG PEOPLE


114
danielllensimadanielllensima
Career27 Sept 2026

Sometimes, you’re not broke because you lack opportunities—you just haven’t discovered the right one yet.

Affiliate marketing is the new oil well/ Money
325
iwilltrainupachildiwilltrainupachild
Parenting3 Oct 2026

🎙️ Episode 073 | Helping Children Develop a Heart for God’s Word | Train up a Child Parenting Podcast

Scholarship 🎓 for our children 👶 For children/wards from birth to SSS 3 💳 Registration Form: ₦200 🏢 Powered by LAUGHTERNGO VENTURES
112
temmytemmy
Others21 Jul 2026

Five Reasons Nigeria's Tech Industry Is Making Headlines

From Nigeria becoming Africa's highest-ranked country for Responsible AI to a Nigerian startup winning a global UN innovation prize, this week brought major developments across artificial intelligence, innovation, startups, digital safety, and technology leadership.
48
kawgo12345kawgo12345
Services28 Sept 2026

DEVELOP THE BIRTHDAY OPPORTUNITY MINDSET

Is it just an expense or could it be an opportunity? 
Discover the mindset behind the Birthday Goldmine. 
105
temmytemmy
Career17 Jul 2026

The "Olodo Uprising": Is Nigeria Rewarding Virality Over Knowledge?

A comment by rapper YCee on the Afropolitan Podcast sparked one of Nigeria's biggest online debates after he described what he called an "Olodo Uprising." The phrase quickly became a trending topic, with many asking whether social media has shifted society's priorities from knowledge and expertise to popularity and virality. But beyond the memes and heated opinions lies a deeper conversation about education, content creation, and success in today's digital age.
97
iwilltrainupachildiwilltrainupachild
Parenting4 Oct 2026

🎙️Episode 075 | Living for God Daily: Encouraging a Lifelong CommitmentTrain up a Child Parenting Podcast

Scholarship 🎓 for our children 👶 For children/wards from birth to SSS 3 💳 Registration Form: ₦200 🏢 Powered by LAUGHTERNGO VENTURES
80
kawgo12345kawgo12345
Services29 Sept 2026

WHO ARE YOU SERVING?

Discover why knowing your audience changes everything.
136
temmytemmy
Money28 Jul 2026

₦5 Million Won't Make You Rich. What You Do Next Will.

It could be years of savings, a contract that finally paid, gratuity from work, or the biggest payment your business has ever received.

One morning, you open your banking app and see ₦5,000,000.

Now comes the part nobody prepares you for.
109