Apache's log location depends on the distribution. On Debian and Ubuntu the error log is /var/log/apache2/error.log and the access log is /var/log/apache2/access.log. On RHEL, CentOS, Fedora, and Amazon Linux they are /var/log/httpd/error_log and /var/log/httpd/access_log (note the underscore and lack of file extension). The paths are defined by the ErrorLog and CustomLog directives in the main config (/etc/apache2/apache2.conf or /etc/httpd/conf/httpd.conf), and virtual hosts usually set their own per-site files.
Quick Reference: Apache Log File Paths
| Platform / Install method | Access log | Error log |
|---|---|---|
Ubuntu / Debian (apt, apache2) | /var/log/apache2/access.log | /var/log/apache2/error.log |
RHEL / CentOS / Fedora (httpd) | /var/log/httpd/access_log | /var/log/httpd/error_log |
Amazon Linux (httpd) | /var/log/httpd/access_log | /var/log/httpd/error_log |
SUSE / openSUSE (apache2) | /var/log/apache2/access_log | /var/log/apache2/error_log |
| Source build (default prefix) | /usr/local/apache2/logs/access_log | /usr/local/apache2/logs/error_log |
| Homebrew (macOS, Apple Silicon) | /opt/homebrew/var/log/httpd/access_log | /opt/homebrew/var/log/httpd/error_log |
Docker (official httpd image) | stdout (docker logs) | stderr (docker logs) |
| Per-vhost (common override) | /var/log/apache2/<site>-access.log | /var/log/apache2/<site>-error.log |
How to View and Tail Apache Logs
Follow the live access log on Debian/Ubuntu:
sudo tail -f /var/log/apache2/access.log
On RHEL/CentOS:
sudo tail -f /var/log/httpd/access_log
Watch both error and access logs at once:
sudo tail -f /var/log/apache2/error.log /var/log/apache2/access.log
Find 500-series errors in the access log:
sudo grep -E ' 50[0-9] ' /var/log/apache2/access.log
Show the busiest URLs:
sudo awk '{print $7}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head
In Docker, read stdout/stderr:
docker logs -f <container>
Finding the Exact Path When It Varies
List the resolved server settings and per-vhost configs:
# Debian/Ubuntu
sudo apachectl -S
# RHEL/CentOS
sudo httpd -S
Dump the active log directives directly from the parsed config:
sudo apachectl -t -D DUMP_RUN_CFG 2>/dev/null
grep -RniE 'ErrorLog|CustomLog|TransferLog' /etc/apache2/ /etc/httpd/ 2>/dev/null
CustomLog and TransferLog define access logs; ErrorLog defines the error log. Paths inside <VirtualHost> blocks override the global ones for that site.
Ubuntu / Debian Detail
The global directives sit in /etc/apache2/apache2.conf, but the default site (/etc/apache2/sites-available/000-default.conf) sets ${APACHE_LOG_DIR}/error.log and ${APACHE_LOG_DIR}/access.log, where APACHE_LOG_DIR is defined as /var/log/apache2 in /etc/apache2/envvars. Change a path, test, and reload:
sudo apachectl configtest
sudo systemctl reload apache2
RHEL / CentOS / Fedora Detail
Config lives in /etc/httpd/conf/httpd.conf with extra files in /etc/httpd/conf.d/. SELinux confines where httpd may write; if you relocate logs, label the new directory:
sudo semanage fcontext -a -t httpd_log_t "/data/logs(/.*)?"
sudo restorecon -Rv /data/logs
sudo systemctl reload httpd
Docker Detail
The official httpd image configures ErrorLog /proc/self/fd/2 and a CustomLog /proc/self/fd/1 common, routing logs to stderr/stdout so docker logs works immediately. To persist files, mount a volume:
docker run -v /host/apache-logs:/usr/local/apache2/logs httpd
docker inspect --format '{{.LogPath}}' <container>
Changing the Log Location and Format
Define a LogFormat and point a vhost at custom files:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
<VirtualHost *:80>
ServerName example.com
ErrorLog /var/log/apache2/example.com-error.log
CustomLog /var/log/apache2/example.com-access.log combined
LogLevel warn
</VirtualHost>
LogLevel accepts debug, info, notice, warn, error, crit, alert, and emerg, and supports per-module levels like LogLevel info ssl:warn.
Log Rotation
On Debian/Ubuntu, /etc/logrotate.d/apache2 rotates weekly:
/var/log/apache2/*.log {
weekly
missingok
rotate 14
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
if invoke-rc.d apache2 status > /dev/null 2>&1; then
invoke-rc.d apache2 reload > /dev/null 2>&1
fi
endscript
}
On RHEL, /etc/logrotate.d/httpd rotates daily and signals httpd to reopen logs. Force a test run with:
sudo logrotate -f /etc/logrotate.d/apache2
Common Errors You'll Find in Apache Logs
AH01630: client denied by server configuration— aRequire/Allow,Denyrule blocked the request; surfaces as 403.AH00072: make_sock: could not bind to address 0.0.0.0:80— another process already holds the port; stop the conflicting service.(13)Permission denied: AH00035: access to / denied— Apache's user (www-dataorapache) lacks read access or SELinux blocked it.AH01071: Got error 'Primary script unknown'— PHP-FPM cannot find the script path passed by Apache; checkSCRIPT_FILENAMEand document root.AH00558: Could not reliably determine the server's fully qualified domain name— harmless startup warning; setServerNameto silence it.File does not exist: /var/www/html/favicon.ico— a request for a missing file logged at error level; usually noise, returns 404.
Troubleshooting: Logs Missing or Empty
- Wrong distro path — you are looking in
/var/log/apache2on a RHEL box where logs are in/var/log/httpd, or vice versa. - Per-vhost logs — global logs are empty because each site writes to its own file; run
apachectl -Sto map vhosts to configs. - Permissions — logs are mode 640 owned by root; use
sudoto read them. - Startup failures — if Apache won't start, the error may only appear in
journalctl -u apache2orjournalctl -u httpd, not in the log file. - Docker — the official image has no log files inside; use
docker logs. - Not reloaded — after changing a path, run
apachectl configtest && systemctl reload apache2; Apache keeps the old file open otherwise.