# Azure App Service SSL: free managed certificate, SNI binding

> Secure an Azure App Service custom domain with the free managed certificate or your own PFX, bind it with SNI, enforce HTTPS Only and TLS 1.2.

Source: https://ssl.sh/guides/azure-app-service-ssl/
Last updated: 2026-11-10

Azure App Service secures a custom domain such as `www.example.com` with a free App Service managed certificate or your own certificate, bound to the hostname with SNI SSL. **HTTPS Only** redirects HTTP requests, and the minimum inbound TLS version should be 1.2.

Steps follow Azure App Service (multitenant) as of November 2026, in the Azure portal or Azure CLI. The apex `example.com` is optional.

## Prerequisites

The custom domain must already be mapped to the app.

- An App Service app on the Basic, Standard, Premium or Isolated tier.
- The custom domain added under **Custom domains**: `www.example.com` with a CNAME directly to `<app-name>.azurewebsites.net`, or `example.com` with an A record to the app's IP (plus the TXT verification record).
- For the apex domain, no access restrictions on the app.
- CAA records, if any, allowing DigiCert; check with the [CAA checker](https://ssl.sh/tools/caa-checker/).
- Azure CLI (`az login`) if you prefer the command line.

## Step 1: Create the free managed certificate

In the portal: open the app → **Settings → Certificates → Managed certificates → Add certificate**, choose the custom domain, click **Validate**, then **Add**. Or with the CLI:

```bash
az webapp config ssl create --resource-group my-rg --name my-app --hostname www.example.com
```

To use your own certificate instead, go to **Bring your own certificates (.pfx) → Add certificate** and upload a password-protected PFX that contains the full chain (see the FAQ for the OpenSSL options).

## Step 2: Bind the certificate to the domain

In **Custom domains**, select **Add binding** for `www.example.com`, choose the certificate and **SNI SSL**. With the CLI, use the thumbprint from Step 1:

```bash
THUMB=$(az webapp config ssl list --resource-group my-rg \
  --query "[?subjectName=='www.example.com'].thumbprint | [0]" -o tsv)
az webapp config ssl bind --resource-group my-rg --name my-app \
  --certificate-thumbprint "$THUMB" --ssl-type SNI
```

## Step 3: Enforce HTTPS and a minimum TLS version

**HTTPS Only** redirects every HTTP request to HTTPS, and the minimum TLS version refuses connections below TLS 1.2:

```bash
az webapp update --resource-group my-rg --name my-app --https-only true
az webapp config set --resource-group my-rg --name my-app --min-tls-version 1.2
```

In the portal these are **Settings → Configuration → General settings → HTTPS Only** and **Minimum inbound TLS version**.

## Verify

The domain should present the bound certificate, and HTTP should redirect to HTTPS. Check it with the [SSL checker](https://ssl.sh/tools/ssl-checker/), or from any terminal:

```bash
curl ssl.sh/www.example.com
curl -sI http://www.example.com | grep -iE '^(HTTP|location)'
```

In Azure:

```bash
az webapp config ssl list --resource-group my-rg --query "[].{name:subjectName,expires:expirationDate,thumb:thumbprint}" -o table
```

## Automatic renewal

The managed certificate renews automatically and App Service updates its bindings, as long as the prerequisites stay the same: the CNAME still points directly at the app, the apex A record still targets it, no IP restriction blocks validation, and CAA still allows DigiCert. Certificates imported from Key Vault (including App Service certificates) sync within 24 hours after they renew. Uploaded PFX files are never renewed: upload the new one, use **Update binding**, then delete the old one. With public lifetimes capped at 200 days since March 15, 2026, prefer the managed or Key Vault options, and add the domain to [ssl.sh monitoring](https://ssl.sh/monitor/) (in development).

## Troubleshooting

- **Validation fails when creating the managed certificate**: the CNAME goes through an intermediate name (for example a CDN) or the apex A record points elsewhere; fix DNS and retry.
- **CAA error**: allow DigiCert; see [CAA record prevents issuance](https://ssl.sh/errors/caa-record-prevents-issuance/).
- **Browser shows the *.azurewebsites.net certificate**: the binding is missing; see [NET::ERR_CERT_COMMON_NAME_INVALID](https://ssl.sh/errors/net-err-cert-common-name-invalid/).
- **PFX upload rejected**: the file was exported with OpenSSL 3 defaults or lacks the chain; re-export as described in the FAQ, or convert with the [SSL converter](https://ssl.sh/tools/ssl-converter/).
- **Old clients cannot connect after raising the minimum TLS version**: see [ERR_SSL_VERSION_OR_CIPHER_MISMATCH](https://ssl.sh/errors/err-ssl-version-or-cipher-mismatch/).
