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
ServerNameorServerAliasmatches theHostheader 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
ServerNameout of a VirtualHost, it inherits the server-wideServerName. 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 nameis a warning that the server-wideServerNameis missing. On Ubuntu, write a singleServerNameline (for exampleServerName server1.example.com) in/etc/apache2/conf-available/servername.confand enable it withsudo a2enconf servername. On RHEL-family systems, setServerNameinhttpd.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 -Sto 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 withsudo 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
- Setting up Apache VirtualHosts
- How to redirect www and non-www in Apache
- Setting up an SSL certificate on Apache with Certbot
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)