Azure / Azure/static-web-apps

Custom domain returns intermittent 404 after Static Web App recreation with the same domain name

Open
#1,785 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
346
Forks
67
PR merge metrics
No merged PRs in 30d

Description

## Describe the bug

After two Static Web Apps were destroyed and recreated with the **same custom domain names**, requests to those custom domains return HTTP 404 for roughly half of all requests, while the auto-generated `*.azurestaticapps.net` hostnames serve correctly 100% of the time.

The custom domains report `status: Ready` in the control plane and DNS resolves correctly, so this looks like stale or partially-applied hostname mappings on the edge fleet rather than a configuration problem on our side.

## Environment

- Region: West Europe
- Two apps in the same resource group, Free tier, each with one custom domain:
- `swa-A` → `lemon-hill-030e51403.7.azurestaticapps.net` → custom domain `crm.bricktech.es`
- `swa-B` → `ashy-sea-037a18303.7.azurestaticapps.net` → custom domain `portal.bricktech.es`
- Both custom domains are CNAMEs proxied through Cloudflare; validation via `dns-txt-token`.
- Subscription ID available on request (omitted here since this issue is public).

## Timeline

| Time (UTC, 2026-08-01) | Event |
|---|---|
| 09:20 | Both Static Web Apps accidentally deleted (Terraform run against the wrong state) |
| ~11:00 | Both apps recreated with new auto-generated hostnames; custom domains re-added |
| 11:04 | `crm.bricktech.es` reaches `Ready` on the recreated app |
| ~12:00 | Intermittent 404s observed on both custom domains |
| 20:08 | `crm.bricktech.es` deleted and re-registered, hoping to clear the state; validation completes, `Ready` again |
| 22:10 | Still ~50% HTTP 404 on `crm.bricktech.es`; `portal.bricktech.es` (never re-registered) fluctuates between ~65% and 100% success |

## To Reproduce

```bash
for i in $(seq 1 20); do
curl -s -o /dev/null -w "%{http_code} " "https://crm.bricktech.es/?cachebust=$RANDOM"
done
# → e.g. 404 200 404 200 200 200 404 200 404 200 200 404 200 200 404 200 200 200 404 200
```

The auto-generated hostname, by contrast, is consistently healthy:

```bash
for i in $(seq 1 20); do
curl -s -o /dev/null -w "%{http_code} " "https://lemon-hill-030e51403.7.azurestaticapps.net/?cachebust=$RANDOM"
done
# → 200 200 200 200 200 ... (20/20)
```

## Expected behavior

Once a custom domain reports `Ready`, all edge nodes should serve it consistently.

## Additional context

**1. The mixed responses come from a single IP.** The app resolves through Traffic Manager to one address, and that same address alternates 404/200 across requests — so the inconsistency is between backend instances behind it, not between DNS answers.

**2. Transient canonical-redirect inconsistency.** For a period, the auto-generated hostname of `swa-A` responded `301` redirecting to the custom domain on some nodes, while other nodes served content for that same hostname normally. This made a common workaround (reverse-proxying to the auto-generated hostname) produce a redirect loop for end users. The 301s later stopped appearing without any change on our side. Meanwhile `swa-B`'s auto-generated hostname never redirected, despite having an equivalent single-custom-domain configuration.

**3. Re-registering the custom domain did not help.** Deleting and re-adding `crm.bricktech.es` completed validation normally but did not resolve the intermittent 404s.

## Questions

1. Is there a known issue when a Static Web App is deleted and a new one is created that re-uses the same custom domain name — can stale mappings from the deleted app persist on part of the edge fleet?
2. Is there a supported way to force a refresh of custom-domain mappings across the fleet?
3. What is the expected propagation window after a custom domain reaches `Ready`? The documentation does not state one, which makes it hard to tell "still propagating" apart from "stuck".
4. Is there a recommended procedure when recreating a Static Web App that must keep the same custom domain (for example, a required waiting period before re-adding it)?

We currently mitigate by routing traffic through a Cloudflare Worker that addresses the origin by its auto-generated hostname, but that is a workaround and it conflicts with the canonical redirect described in point 2.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.