// Web Server · Apache HTTP
Apache HTTP Server Logs
Apache produces two primary logs: the access log records every HTTP request, while the error log captures problems, warnings, and server notices. Both formats and locations are configurable in httpd.conf or per-vhost.
Access Log
Default location: /var/log/apache2/access.log (Debian/Ubuntu) or /var/log/httpd/access_log (RHEL/CentOS). The most common format is Combined, an extension of CLF adding referrer and user-agent.
203.0.113.42
-
frank
[10/Apr/2025:13:55:36 -0500]
"GET
/index.html
HTTP/1.1"
200
2326
"https://example.com/page"
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"
%h Client IP
%u Auth user
%t Timestamp
%m Method / Protocol
%U Request URI
%>s HTTP Status
%b Bytes
Referer
User-Agent
| Format Token | Name | Description |
|---|---|---|
| %h | Client host | The remote host IP. If HostnameLookups On, resolved to DNS (slow — avoid in production). |
| %l | Ident | RFC 1413 ident lookup. Almost always -. Requires identd on client. Ignore in production. |
| %u | Auth username | Authenticated user via HTTP Basic/Digest. Hyphen if unauthenticated. Not the OS user. |
| %t | Timestamp | Request time in format [day/month/year:HH:MM:SS ±offset]. Offset is server's UTC offset. |
| %r | Request line | Full first HTTP line: method, URI, protocol. E.g. GET /path?q=1 HTTP/2. |
| %s / %>s | Status code | %s = first internal status; %>s = final status after redirects. Always prefer %>s. |
| %b / %B | Bytes sent | %b = body bytes, hyphen if zero. %B = always numeric. Headers not included. |
| %{Referer}i | Referrer | Linking page URL from HTTP Referer header. May be empty or spoofed. |
| %{User-Agent}i | User-Agent | Client identifier string. Can be spoofed. Useful for bot detection. |
| %T / %D | Response time | %T = seconds (integer); %D = microseconds. Add for performance profiling. |
| %{X-Forwarded-For}i | Real IP (proxy) | Client's actual IP when behind CDN/load balancer. Use mod_remoteip to trust this automatically. |
| %v | Virtual host | ServerName of the vhost serving the request. Essential in shared-hosting combined logs. |
| %p | Port | Canonical server port (80, 443). |
| %a | Client IP (accurate) | Remote IP after mod_remoteip processing — preferred over %h when behind proxy. |
💡 Pro Tip
Add %D (microseconds) to your LogFormat and grep for values over 2,000,000 (2 seconds) to quickly identify slow pages causing user-visible latency.
Error Log
Default: /var/log/apache2/error.log. Uses a different format than the access log. Apache 2.4+ uses a structured bracketed format.
[Thu Apr 10 14:01:32.456789 2025]
[error]
[pid 12345:tid 140234]
[client 203.0.113.42:55123]
File does not exist: /var/www/html/favicon.ico
Timestamp
Log Level
PID:TID
Client IP:port
Error message
Severity Levels
| Level | Value | Meaning & Common Causes |
|---|---|---|
| emerg | 0 | System unusable. Apache cannot start. Port binding failure, config parse error. Immediate action required. |
| alert | 1 | Action must be taken immediately. Child process failures, rare. |
| crit | 2 | Critical conditions. SSL certificate load failures, socket errors. |
| error | 3 | Non-fatal errors. Permission denied, missing files, PHP fatal errors, upstream proxy failures. Most common actionable level. |
| warn | 4 | Warnings. Config mismatches, deprecated directives, mod_rewrite notes. |
| notice | 5 | Normal informational events. Server start/stop, graceful restart, config reload. |
| info | 6 | Verbose info. Request lifecycle details. |
| debug | 7 | All debug output. Floods disk — dev only, never in production. |
| trace1–8 | 8–15 | Module-level tracing (e.g. mod_rewrite step-by-step). Use very sparingly. |
Common Error Messages Decoded
| Error Message | Cause | Fix |
|---|---|---|
| Permission denied: /path | Apache user (www-data/apache) can't read the file | chown www-data:www-data /path or chmod 644 |
| File does not exist: /path | 404 — file missing, wrong DocumentRoot | Check DocumentRoot, aliases, and rewrite rules |
| proxy: error reading status line from remote | Backend closed connection prematurely | Check upstream health, timeout settings, keepalive config |
| SSL_do_handshake failed | TLS failure — cipher mismatch, expired cert, old TLS version | Check SSLProtocol, SSLCipherSuite, cert expiry |
| AH01630: client denied by server configuration | Require directive blocking client | Review <Directory> blocks and Require directives |
| caught SIGTERM, shutting down | Graceful shutdown requested | Normal — service restart or apachectl graceful |
| server reached MaxRequestWorkers | All worker slots full; new connections queued/dropped | Tune MaxRequestWorkers, investigate slow requests, check memory |
| client sent HTTP/1.1 request without hostname | Malformed request missing Host header | Usually a scanner. Ignore or block via mod_security |
Log Format Configuration
httpd.conf
# Common Log Format (CLF) LogFormat "%h %l %u %t \"%r\" %>s %b" common # Combined (CLF + Referer + User-Agent) — most common LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined # Combined + response time in microseconds (recommended for perf monitoring) LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" combined_time # Vhost combined — all vhosts in one file, differentiated by hostname:port LogFormat "%v:%p %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined # JSON — machine-parseable, great for Filebeat/Fluentd/Loki shippers LogFormat "{ \"time\":\"%t\", \"ip\":\"%a\", \"host\":\"%V\", \"method\":\"%m\", \ \"uri\":\"%U%q\", \"status\":\"%>s\", \"bytes\":\"%B\", \ \"referer\":\"%{Referer}i\", \"ua\":\"%{User-Agent}i\", \"ms\":%D }" json # Apply formats CustomLog /var/log/apache2/access.log combined ErrorLog /var/log/apache2/error.log LogLevel warn
ℹ Default Log Paths
Debian/Ubuntu: /var/log/apache2/ ·
RHEL/CentOS: /var/log/httpd/ ·
macOS Homebrew: /usr/local/var/log/httpd/ ·
Windows: C:\Apache24\logs\
HTTP Status Code Reference
// 2xx — Success
200
OK
Request succeeded. Body contains the response.
201
Created
Resource created (POST/PUT). Location header present.
204
No Content
Success, no body. Common for DELETE and OPTIONS preflight.
206
Partial Content
Range request served. Expected for video streaming.
// 3xx — Redirection
301
Moved Permanently
URL changed forever. SEO juice transfers. Update bookmarks.
302
Found (Temp)
Temporary redirect. Original URL still valid.
304
Not Modified
Cache still valid. ETag/If-Modified-Since matched. No body.
307
Temporary Redirect
Like 302 but HTTP method must not change.
308
Permanent Redirect
Like 301 but method must not change.
// 4xx — Client Errors
400
Bad Request
Malformed syntax, invalid framing, oversized headers.
401
Unauthorized
Authentication required. WWW-Authenticate header present.
403
Forbidden
Authenticated but not authorized, or IP blocked.
404
Not Found
Resource doesn't exist. Check DocumentRoot and aliases.
405
Method Not Allowed
HTTP method not permitted for this resource.
408
Request Timeout
Client too slow sending request. Often bot/scanner.
413
Content Too Large
Body exceeds LimitRequestBody. Common with uploads.
429
Too Many Requests
Rate limiting. Requires mod_ratelimit or reverse proxy.
// 5xx — Server Errors
500
Internal Server Error
Generic server error. Check error log — PHP fatal, CGI crash.
502
Bad Gateway
Upstream returned invalid response. Backend down or socket error.
503
Service Unavailable
Overloaded or maintenance. MaxRequestWorkers hit, backend unhealthy.
504
Gateway Timeout
Upstream too slow. Increase ProxyTimeout or fix backend.