Share via

App Service custom domain returns 400 Invalid Hostname after binding succeeds — routing-table state stuck on cluster

Tom Bauto 5 Reputation points
2026-05-17T15:49:52.7966667+00:00

Summary

A newly provisioned App Service Linux (B1) in southeastXXXX rejects ALL custom-domain HTTPS requests with HTTP 400 Bad Request — Invalid Hostname, even though every customer-side configuration is correct (DNS, hostname binding, SSL cert, asuid TXT record). The same cluster's other App Service (same plan, sibling resource) serves its own custom domains without issue. Recreating the affected App Service from scratch did not resolve. Looking for confirmation this is a platform-side routing-table state that needs Microsoft to flush, or guidance on what else to try.

Topology

  • Region: southeastXXXX
  • App Service Plan: Linux B1, shared between two sites:
    • Site A (Portal) — bound example.com + www.example.com, both Secured (SNI SSL), works fine, returns app content.
    • Site B (API) — newly provisioned. Default *.azurewebsites.net hostname works. Any custom domain bound to it returns 400.
  • Cluster (per nslookup): waws-prXX-sXX-113.sip.azurewebsites.windows.net / IP 20.212.x.x
  • Both sites are in the same resource group, same subscription, same managed identity pattern.

Symptom

$ curl -v https://api.example.com/health
HTTP/1.1 400 Bad Request
Server: Microsoft-Azure-Application-Gateway/v2

<h2>Bad Request - Invalid Hostname</h2>
<p>HTTP Error 400. The request hostname is invalid.</p>

The default hostname on the SAME App Service works:

$ curl https://<my-api-app>.azurewebsites.net/health
Healthy

Same 400 for a second test subdomain (app.example.com) bound to the same site. So it's not specific to one hostname — it's any custom domain on this particular App Service.

What I verified

  1. DNS resolves correctly to the App Service's IP via the standard *.azurewebsites.net CNAME chain:
       $ nslookup api.example.com
       Aliases: api.example.com
                <my-api-app>.azurewebsites.net
                waws-prod-sg1-113.sip.azurewebsites.windows.net
       Address: 20.212.x.x
    
  2. Hostname binding exists with correct SSL (per az webapp config hostname list):
       HostNameType  Name                SslState     Thumbprint
       ------------  ------------------  -----------  --------------------------------
       Verified      api.example.com     SniEnabled   <thumbprint>
       Verified      app.example.com     SniEnabled   <thumbprint>
    
  3. Certificate is healthy — App Service Managed Certificate, keyVaultSecretStatus: Succeeded, correct expiration. TLS handshake from the client serves the correct certificate (verified via System.Net.Security.SslStream.AuthenticateAsClient):
       Subject: CN=api.example.com
       Issuer:  CN=GeoTrust TLS RSA CA G1, OU=www.digicert.com, O=DigiCert Inc, C=US
    
    So TLS terminates correctly. The 400 comes after TLS, from Azure's edge HTTP router.
  4. asuid TXT record is present at the DNS provider (Namecheap):
       $ nslookup -type=TXT asuid.api.example.com
       asuid.api.example.com  text = "<verification-id>"
    
    Matches the App Service's customDomainVerificationId.
  5. No competing hostname binding anywhere in the subscription:
       $ az resource list --resource-type Microsoft.Web/sites/hostNameBindings -o table | findstr api.example.com
       (no other results)
    
  6. Recreated the App Service from scratch via az webapp delete --keep-empty-plan + Bicep redeploy. Same symptom on the new instance. The recreate landed on the same cluster.
  7. Sibling app on the same plan + same cluster works. It has example.com + www.example.com bound the same way and they serve fine. So the cluster's edge router CAN route custom domains — it just doesn't have a route for the new App Service.

What I tried (in order)

AttemptOutcome1. az webapp config ssl bind against original certBind succeeded, still 400.2. Delete + recreate hostname bindingStill 400.3. Delete + recreate the Managed Certificate, rebindStill 400.4. az webapp restartStill 400.5. App Service Plan SKU bounce (B1 → S1 → B1) to force cluster reassignmentStill 400 (landed on same cluster).6. Full az webapp delete --keep-empty-plan + Bicep redeploy + rebindStill 400.7. Add asuid.api.example.com TXT record matching customDomainVerificationIdStill 400.8. Test with a different subdomain (app.example.com) — fresh hostname, fresh certStill 400.## Question for the community / Microsoft

  • Is this a known scenario where the App Service edge router caches a bad routing state for a recreated resource that needs Microsoft-side intervention to flush?
  • Is there any customer-accessible way to force the edge router's routing table to re-read the hostname bindings, short of moving to a new App Service Plan in a different cluster?
  • For people who've hit this: what unstuck it for you?

Happy to share resource IDs / subscription details privately if needed for diagnosis.

Environment / version info:

  • Linux App Service, .NET runtime stack
  • Region: Southeast XXXX
  • App Service Plan SKU: B1 (Linux)
  • App Service Managed Certificate (free SNI SSL)
  • Custom domain bound via az webapp config hostname add + ssl create + ssl bind CLI sequence
Azure App Service
Azure App Service

Azure App Service is a service used to create and deploy scalable, mission-critical web apps.


1 answer

Sort by: Most helpful
  1. Alex Burlachenko 21,310 Reputation points MVP Volunteer Moderator
    2026-05-18T08:57:30.1766667+00:00

    Tom Bauto hi,

    u already ruled out normal DNS/cert mistakes, this now looks like stale hostname propagation/routing state on the App Service front-end cluster, honestly this does look like stale/broken App Service edge routing state, not customer DNS/cert config anymore. u already proved the important parts: DNS chain resolves correctly, TLS handshake serves the right cert, hostname binding exists and is verified, no duplicate hostname elsewhere, and the default *.azurewebsites.net hostname works. That means the failure is happening after TLS, at the App Service front-end routing layer. The fact that the sibling app on the same cluster works while every custom hostname on this one app returns 400 Invalid Hostname is the big clue.

    The other strong signal is that deleting/recreating the app did not help because it landed back on the same cluster (waws-prod-sg1-113). That points away from the app container/runtime and toward stale hostname propagation or corrupted front-end routing metadata on that cluster.

    At this point I would stop redoing bindings certs. two things ....

    1. move the app to a completely different App Service Plan/cluster (not just SKU bounce on same plan). Create a temporary new Linux plan in another region stamp if possible, deploy app there, bind hostname, test.
    2. Open a ticket and ask specifically for App Service front-end hostname routing refresh / stale hostname cleanup on the cluster. Include the hostname, app name, cluster name, timestamps, and the fact that TLS succeeds but HTTP routing fails with Invalid Hostname.

    the response header Microsoft-Azure-Application-Gateway/v2 is interesting because standard App Service front-ends usually do not expose that header directly. I would double-check there is no Front Door/App Gateway/CDN layer still pointing at the old app/site config somewhere in DNS/proxy chain, even indirectly. But since the default hostname works and cert is correct, I still lean platform routing metadata.

    rgds,

    Alex

    &

    If my answer was helpful pls mark it and additional thx if u follow me at Q&A portal
    

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.