Resolving Apache VirtualHost Conflict When ServerName Directive is Ignored Due to Hostname Configuration


2 views

After changing my server's hostname to match one of my hosted domains and updating /etc/hosts, Apache began serving the default "It works!" page instead of my configured VirtualHost for the naked domain (domain.com). The www-prefixed version (www.domain.com) works correctly regardless of whether 000-default is enabled.

The apache2ctl -S output reveals the root cause:

VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
*:80                   is a NameVirtualHost
         default server domain.com (/etc/apache2/sites-enabled/000-default:1)
         port 80 namevhost domain.com (/etc/apache2/sites-enabled/000-default:1)
         port 80 namevhost other.com (/etc/apache2/sites-enabled/other:1)
         port 80 namevhost another.com (/etc/apache2/sites-enabled/another:1)
         port 80 namevhost domain.com (/etc/apache2/sites-enabled/domain:1)

This shows that both the default VirtualHost and our custom configuration are claiming domain.com as their ServerName.

When you set the server's hostname to match a hosted domain AND configure it in /etc/hosts, Apache's default behavior changes:

  • The system hostname automatically becomes a ServerName in the default VirtualHost
  • This creates a direct conflict with your explicit VirtualHost configuration

Instead of completely disabling 000-default (which might cause issues with future services), modify it to avoid the hostname collision:


    ServerName server.internal
    DocumentRoot /var/www/html

Alternatively, you can leave 000-default completely empty:


    ServerName garbage.invalid

For more control, explicitly define your primary domain first in the ports.conf:

NameVirtualHost *:80
Listen 80


    ServerName domain.com
    ServerAlias www.domain.com
    DocumentRoot /srv/www/domain
    
    # Other directives...

Remember to:

  • Run sudo apache2ctl configtest after changes
  • Clear DNS cache on your testing machine
  • Restart Apache (sudo systemctl restart apache2)

This configuration maintains your hostname setup while ensuring proper VirtualHost routing. The solution works for Apache 2.4+ and maintains compatibility with other services that might rely on the system hostname.


After changing my server's hostname to match one of my hosted domains (domain.com) and updating /etc/hosts, Apache started serving the default "It works!" page instead of my configured VirtualHost when accessing the bare domain. Here's what my current setup looks like:


    ServerName domain.com
    ServerAlias www.domain.com
    DocumentRoot /srv/www/domain
    ErrorLog /srv/www/domain/logs/error.log
    CustomLog /srv/www/domain/logs/access.log combined

Running apache2ctl -S revealed the core issue:

VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
*:80                   is a NameVirtualHost
         default server domain.com (/etc/apache2/sites-enabled/000-default:1)
         port 80 namevhost domain.com (/etc/apache2/sites-enabled/domain:1)
Syntax OK

The output shows that 000-default is claiming domain.com as its default server, creating a conflict with our specific VirtualHost configuration.

When we made these changes:

  1. Set server hostname to domain.com
  2. Added domain.com to /etc/hosts pointing to external IP

Apache's default behavior changed because it now sees the hostname matching one of our domains. The 000-default config becomes the first responder for requests to domain.com.

Option 1: Disable 000-default (Simple Fix)

sudo a2dissite 000-default
sudo systemctl reload apache2

Option 2: Modify 000-default (More Flexible)

Edit /etc/apache2/sites-available/000-default.conf:


    DocumentRoot /var/www/html
    # Explicitly deny being default for our domain
    ServerName some-unused-name.local

Option 3: Adjust Hosts File (Alternative Approach)

Modify /etc/hosts to use a subdomain for the hostname:

# Instead of:
# 192.0.2.1 domain.com

# Use:
192.0.2.1 server.domain.com

For production systems, I recommend:


    # Primary domain first
    ServerName domain.com
    # Then all aliases
    ServerAlias www.domain.com server.domain.com
    # Explicit document root
    DocumentRoot /srv/www/domain/public_html
    
    # Log separation
    ErrorLog ${APACHE_LOG_DIR}/domain_error.log
    CustomLog ${APACHE_LOG_DIR}/domain_access.log combined

After making changes:

sudo apache2ctl configtest
sudo systemctl reload apache2
curl -I http://domain.com
curl -I http://www.domain.com

Check the access logs to confirm which VirtualHost is handling requests:

tail -f /var/log/apache2/domain_access.log
tail -f /var/log/apache2/other_access.log