# AH01909: Apache certificate does not match the ServerName

> AH01909 is an Apache startup warning: the vhost's ServerName is not in its certificate's SAN or CN. Usually a missing ServerName or wrong certificate.

Source: https://ssl.sh/errors/apache-ah01909-certificate-does-not-include-id/
Last updated: 2026-11-10

**AH01909 means Apache's mod_ssl found that the certificate for a virtual host does not contain that host's ServerName.** Apache logs it as a startup warning and keeps running, but clients that use the ServerName get a name mismatch error. The usual causes are a missing ServerName, a typo in it, or the wrong certificate file.

## How to read the message

The part before "server certificate" is built from the virtual host: `ServerName:port`, then `:index` for the certificate within that host. A full log line reads `AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name`. In `www.example.com:443:0`:

| Part | Meaning |
|---|---|
| `www.example.com` | The ServerName Apache compared, or the name it guessed when none is set |
| `443` | The port of the virtual host |
| `0` | First certificate in that vhost (`1` would be a second, for example ECDSA, certificate) |

mod_ssl compares that name with the certificate's DNS names in the Subject Alternative Name and with its Common Name. Wildcards match only the left-most label. ServerAlias names are not checked.

## Why Apache only warns

Apache cannot know which names clients will use. A virtual host may answer for aliases, for an IP address behind a load balancer, or only as a fallback, and the certificate may legitimately cover those instead. So mod_ssl logs the mismatch at warning level and continues. Browsers have no such leeway: under [RFC 9525](https://www.rfc-editor.org/rfc/rfc9525) and the browsers' own rules, a client that connects by a name missing from the certificate's subject alternative names rejects the connection. AH01909 is the server-side early warning of the browser errors [NET::ERR_CERT_COMMON_NAME_INVALID](https://ssl.sh/errors/net-err-cert-common-name-invalid/) and [SSL_ERROR_BAD_CERT_DOMAIN](https://ssl.sh/errors/ssl-error-bad-cert-domain/).

## Related mod_ssl startup messages

| Code | Level | Text (abridged) | Meaning |
|---|---|---|---|
| AH01906 | warning | server certificate is a CA certificate | A CA certificate was configured as the server certificate |
| AH01907 | warning | server certificate is not a leaf certificate | The certificate allows issuing further certificates |
| **AH01909** | warning | server certificate does NOT include an ID which matches the server name | ServerName not in the certificate |
| AH02572 | emergency | Failed to configure at least one certificate and key | No usable certificate and key, Apache does not start; see [AH02572](https://ssl.sh/errors/apache-ah02572-failed-to-configure-certificate/) |

## Common causes, most frequent first

### 1. The SSL virtual host has no ServerName

Distribution defaults such as `default-ssl.conf` ship without a ServerName. Apache's documentation says a name-based virtual host without ServerName gets a name derived from the system hostname, so the warning shows `localhost`, the machine name or a reverse-DNS name. If you also see AH00558 ("Could not reliably determine the server's fully qualified domain name"), the global ServerName is missing too.

### 2. The certificate does not cover the ServerName

The vhost says `ServerName example.com` but the certificate was issued only for `www.example.com`, or a wildcard `*.example.com` is used for the bare domain. List the certificate's names:

```bash
openssl x509 -in /etc/ssl/certs/example.com.crt -noout -subject -ext subjectAltName
```

### 3. The vhost points at the wrong certificate file

After a renewal or migration, `SSLCertificateFile` still points to an old certificate, a snakeoil placeholder (`ssl-cert-snakeoil.pem` on Debian and Ubuntu) or another site's certificate. Check what each vhost loads:

```bash
apachectl -S
grep -RniE 'ServerName|SSLCertificateFile' /etc/apache2/sites-enabled/ /etc/httpd/conf.d/ 2>/dev/null
```

`apachectl -S` lists every virtual host with its file and line, which helps when several vhosts share port 443.

### 4. A catch-all or default vhost

A deliberate default vhost that answers unknown names with some certificate will always log AH01909. That is expected if you know it is there.

## How to fix it

Make the ServerName and the certificate agree: set the name explicitly, then use a certificate that covers it.

**1. Give every SSL vhost an explicit ServerName** and list other names in ServerAlias:

```apache
<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
```

Since Apache 2.4.8, `SSLCertificateFile` can contain the intermediate certificates as well, so point it at the full chain.

**2. Get a certificate that covers every name** in ServerName and ServerAlias:

```bash
sudo certbot --apache -d example.com -d www.example.com
```

See [Apache with Let's Encrypt](https://ssl.sh/guides/apache-lets-encrypt-certbot/).

**3. Set a global ServerName** in `apache2.conf` or `httpd.conf` so default vhosts do not depend on the system hostname.

**4. Disable unused default SSL sites** (`a2dissite default-ssl` on Debian and Ubuntu) if they only serve a placeholder certificate.

## How to verify the fix

1. `apachectl configtest` returns `Syntax OK`, then reload with `systemctl reload apache2` (or `httpd`).
2. The error log no longer contains AH01909 after the reload:

   ```bash
   grep AH01909 /var/log/apache2/error.log | tail -n 3
   ```

3. Test each name with SNI: `openssl s_client -connect example.com:443 -servername www.example.com </dev/null 2>/dev/null | openssl x509 -noout -ext subjectAltName`, and run the [SSL checker](https://ssl.sh/tools/ssl-checker/) against each hostname.
