Apache and Fully Qualified Domain Names
Have you ever gotten this error when starting Apache on Linux?
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
Most advice I've seen suggests that you simply set the
ServerName value in your
httpd.conf file. That will certainly work. But I find the answer very unsatisfying and even a little misleading.
The quest for a more satisfying answer
I was not completely satisfied with anything I'd read online about this error so far. The goal should really be to solve the underlying issue: having a fully-qualified domain name (FQDN) set on your Linux system that Apache can actually use!
Apache's wiki has the typical advice (set
ServerName and off you go.) But it also ends with the following paragraph:
The presence of this error message also indicates that Apache httpd was unable to obtain a fully-qualified hostname by doing a reverse lookup on your server's IP address. While the above instructions will get rid of the warning in any case, it is also a good idea to fix your name resolution so that this reverse mapping works.
ServerName in httpd.conf will solve the problem for Apache, but you will not have solved this issue for (potentially) other applications. Furthermore, it is my personal feeling that having to set both
httpd.conf with the same information is a violation of the single source of truth principle.
I've done some researching and experimenting and I believe I finally have a fairly complete answer.
Let's look at some Apache source!
The source for Apache can be viewed on Github.
First, the error message we're getting ("Could not reliably determine the server's fully qualified domain name...") is coming from a function named
ap_log_perror(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, a, APLOGNO(00558) "%s: Could not reliably determine the server's fully qualified " "domain name, using %s. Set the 'ServerName' directive globally " "to suppress this message", ap_server_argv0, server_hostname);
To successfully get the FQDN for your system, it calls first
apr_sockaddr_info_get() and then
apr_getnameinfo() (both are part of the Apache Portable Runtime, see source for sockaddr.c here) to get the IP address and then the hostname for the address for your system.
On non-legacy POSIX systems, these functions call the C library functions
Someone please correct me if I'm wrong, but from my skimming of the Apache source and some man pages (links scattered below), it appears that the following occurs:
1. The hostname is requested
The hostname is retrieved with
2. The IP address for the hostname is requested
The IP address for the hostname is retrieved with
3. The FQDN for the IP address is requested
The fully-qualified domain name for the hostname's ip address is retrieved with
It should be noted that
getnameinfo() uses the settings in
/etc/nsswitch.conf to determine the search order to use for resolving addresses to names.
By default on most systems,
/etc/nsswitch.conf will contain a line like
hosts: files dns
files specifically means
/etc/hosts on most systems, so the ultimate meaning is that the contents of /etc/hosts will be checked before DNS.
What to do! (Two steps)
First, set your hostname
This seems to be system-specific
wiggles as our example hostname.
Second, edit /etc/hosts
You'll need an entry in your
/etc/hosts file that resolves your hostname to an IP address AND resolves that IP address to an FQDN.
IP_address canonical_hostname [aliases...]
192.0.2.16 wiggles.example.com wiggles
wiggles.example.com (the FQDN) must come before
wiggles (the hostname).
gethostname() returns the canonical name, which is the first one.
Apache will not be impressed if it does not see a name with at least one
. character. See
ap_get_local_host() in util.c (linked above).
Testing at the command line!
Of course, you can keep editing things and running
to see if Apache is happy yet.
But we can pretty accurately replicate what is happening internally in Apache at the command line using the
Getting the hostname
$ hostname -v gethostname()=`wiggles' wiggles
-v option is for 'verbose'.)
Getting the IP address for the hostname
$ hostname -i 192.0.2.16
(You can also add the
-v option for more detail.)
Getting the FQDN for the IP address
$ getent hosts 192.0.2.16 192.0.2.16 wiggles.example.com wiggles
getent hosts does specifically search in
/etc/hosts. Check your
/etc/nsswitch.conf to double-check the hosts lookup order (see previous information) or write your own Perl script to call the gethostbyaddr function directly!
By incrementally checking each step on the command line, I feel it's much clearer what is happening and where fixes may need to occur.