2026年11月12日

2026年11月12日

Apache ServerName vs ServerAlias: VirtualHosts, www Redirects and SSL

This article is a localized edition of the Japanese original. Read the Japanese original

ServerName and ServerAlias are the settings Apache uses to decide which site (VirtualHost) a request belongs to. Both take domain names, but they do not play the same role. This article explains the difference between the two, then covers unifying the www and non-www addresses and setting up HTTPS.

The examples use Apache 2.4 as of October 2026, with Ubuntu / Debian paths as the baseline; differences on RHEL-family systems (AlmaLinux, Rocky Linux) are noted along the way.

The difference between ServerName and ServerAlias

Item ServerName ServerAlias
How many One per VirtualHost Several, separated by spaces. You can also write several ServerAlias lines
Wildcards Not allowed * and ? are allowed (for example *.example.com)
Role The site's canonical name. Also used to match the VirtualHost Alternative names treated as the same site. Used only for matching
Self-referential URLs Used when Apache builds URLs pointing to itself (with UseCanonicalName On) Not used

Apache compares the request's Host header (the domain name the browser sends) with the ServerName and ServerAlias of the VirtualHosts listening on the same IP address and port, in order, and answers with the VirtualHost that matches.

The key point is that ServerAlias does not redirect. If you write ServerAlias www.example.com, requests to www.example.com get the same content as-is. The address bar keeps showing www.example.com, and to search engines the same page exists at two URLs. To consolidate on one URL, you need a separate redirect, described later.

Which VirtualHost gets chosen

  • The VirtualHost whose ServerName or ServerAlias matches the Host header is chosen.
  • If nothing matches, the first VirtualHost defined for that IP address and port is used (the default site). This also applies when someone accesses the server directly by IP address.
  • If you leave ServerName out of a VirtualHost, it inherits the server-wide ServerName. Then the VirtualHosts can no longer be told apart by name, so write it in every VirtualHost.

Watch out for default sites, such as Ubuntu's 000-default.conf, that load first because of their file names. Site configuration files are read in file-name order within sites-enabled/.

Write a basic VirtualHost

On Ubuntu / Debian, create one configuration file per site in /etc/apache2/sites-available/.

# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public

    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>
sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2

On RHEL-family systems, put the same content in /etc/httpd/conf.d/example.com.conf (use something like logs/example.com-error_log instead of ${APACHE_LOG_DIR}), then apply it with sudo apachectl configtest and sudo systemctl reload httpd. You do not need to edit the main httpd.conf directly.

Unify www and non-www on one URL

To send requests for www.example.com to example.com, create a separate VirtualHost for www and return a permanent (301) redirect with Redirect. Do not list www.example.com as a ServerAlias of the destination VirtualHost.

# VirtualHost that only redirects
<VirtualHost *:80>
    ServerName www.example.com
    Redirect permanent / http://example.com/
</VirtualHost>

# The actual site
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example.com/public
</VirtualHost>

Redirect carries over everything after the given path. A request for http://www.example.com/about/ is redirected to http://example.com/about/. If you use HTTPS, write the destination with https:// (see the next section).

For WordPress, also set "WordPress Address (URL)" and "Site Address (URL)" under Settings → General (設定 → 一般 in the Japanese UI) to the URL you unified on.

HTTPS VirtualHosts and certificates

HTTPS (port 443) is written as a VirtualHost separate from port 80. **Every name in ServerName and ServerAlias must be included in the certificate.** If someone visits with a name the certificate does not cover, the browser shows a certificate error. Even a www VirtualHost that only redirects needs its name in the certificate if it accepts HTTPS.

Here is how to get a certificate covering both names with Let's Encrypt's certbot (on Ubuntu):

sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d example.com -d www.example.com

certbot's Apache plugin builds the HTTPS configuration from the ServerName and ServerAlias of the port 80 VirtualHost. If you write it by hand, it looks like this:

<VirtualHost *:443>
    ServerName www.example.com
    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName example.com
    DocumentRoot /var/www/example.com/public
    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>

# Send all HTTP to the canonical HTTPS URL
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    Redirect permanent / https://example.com/
</VirtualHost>

SSLEngine and related directives need mod_ssl. Enable it with sudo a2enmod ssl on Ubuntu, or sudo dnf install mod_ssl on RHEL-family systems. Since Apache 2.4.8, intermediate certificates go into the file given to SSLCertificateFile (fullchain.pem for Let's Encrypt) rather than SSLCertificateChainFile.

You can separate several HTTPS sites by name on one IP address because the browser sends the domain name through SNI when it opens the TLS connection. All current major browsers support SNI.

Check the configuration

The -S option lists which names are assigned to which VirtualHost.

# Ubuntu / Debian
sudo apache2ctl -S
# RHEL family
sudo apachectl -S

The output shows, for each port, the default VirtualHost (default server) and each VirtualHost's ServerName, alias entries and configuration file location. Confirm that the names you intended are listed and which site is the default.

You can check the actual responses with curl. Even before switching DNS, you can test by pointing --resolve at the server's IP address (192.0.2.10 is an example address).

# Expect 301 and Location: https://example.com/
curl -sI http://www.example.com/
curl -sI --resolve www.example.com:443:192.0.2.10 https://www.example.com/

Common problems

  • AH00558 warning at startup: AH00558: Could not reliably determine the server's fully qualified domain name is a warning that the server-wide ServerName is missing. On Ubuntu, write a single ServerName line (for example ServerName server1.example.com) in /etc/apache2/conf-available/servername.conf and enable it with sudo a2enconf servername. On RHEL-family systems, set ServerName in httpd.conf. It does not affect how VirtualHosts work.
  • A different site appears: no VirtualHost matches the name, so the default site is answering. Use apache2ctl -S to check the spelling of the names and whether the same name appears in more than one VirtualHost. When a name is duplicated, the VirtualHost loaded first is used.
  • Certificate error with www: the certificate does not include www.example.com. You can see the names in the certificate with sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -text | grep -A1 "Subject Alternative Name". To add names, run certbot again with all the names listed with -d.

Related articles

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲