Locating Nginx access and error logs shortens outage triage, supports incident response, and provides a reliable request trail for security controls like rate limiting and allow/deny rules.
The access_log directive records request lines into a configured destination, while error_log captures runtime diagnostics such as upstream failures, TLS issues, and configuration warnings. Both directives can be set globally under http or overridden per server and location blocks, and included snippets (for example from /etc/nginx/conf.d or /etc/nginx/sites-enabled) become part of the effective configuration evaluated at runtime.
Some deployments disable access logging with access_log off, send logs to syslog (syslog:...), or run in containers where logs are written to /dev/stdout or /dev/stderr instead of regular files. Log content can include sensitive URLs, query strings, and client IP addresses, so permissions and log rotation policies should be confirmed before sharing excerpts or widening access.
Related: How to secure Nginx web server
Related: How to configure log rotation for Nginx
Steps to locate Nginx access and error log files:
- Search the effective Nginx configuration for access_log and error_log directives across included files.
$ sudo nginx -T 2>&1 | grep --line-number --extended-regexp '^[[:space:]]*(access_log|error_log)[[:space:]]' | head --lines 20 247: access_log /var/log/nginx/access.log main; 248: error_log /var/log/nginx/error.log warn; 312: access_log /var/log/nginx/example.access.log main; ##### snipped #####
Nginx writes the configuration dump to stderr, so 2>&1 is required when piping; if no matches appear, run sudo nginx -T without filtering to confirm the dump succeeded.
- Show nearby server_name and listen lines to map each log directive to the relevant virtual host.
$ sudo nginx -T 2>&1 | grep --line-number --extended-regexp --context 2 '^[[:space:]]*(server_name|listen|access_log|error_log)[[:space:]]' | head --lines 60 105- server { 106- listen 80; 107- server_name example.com; 108- 109: access_log /var/log/nginx/example.access.log main; 110: error_log /var/log/nginx/example.error.log warn; 111- 112- location / { ##### snipped #####Per-site directives override the global defaults, and the closest enclosing directive is typically the effective destination.
- Extract the unique log destinations currently configured for Nginx.
$ sudo nginx -T 2>&1 | awk '$1 == "access_log" || $1 == "error_log" { dest=$2; sub(/;$/, "", dest); if ($1 == "access_log" && dest == "off") next; print dest }' | sort --unique /var/log/nginx/access.log /var/log/nginx/error.log ##### snipped #####Destinations starting with / are on-disk paths, while syslog:... and stderr are not regular files.
- Confirm the on-disk log files exist with expected ownership and permissions.
$ sudo nginx -T 2>&1 | awk '$1 == "access_log" || $1 == "error_log" { dest=$2; sub(/;$/, "", dest); if ($1 == "access_log" && dest == "off") next; print dest }' | grep --extended-regexp '^/' | sort --unique | xargs --no-run-if-empty sudo ls -la -rw-r----- 1 root adm 8791 Dec 14 09:10 /var/log/nginx/access.log -rw-r----- 1 root adm 2312 Dec 14 09:09 /var/log/nginx/error.log ##### snipped #####Rotated logs are commonly present as access.log.1 or compressed as access.log.2.gz.
- Generate a test request to create a fresh access-log entry.
$ curl --silent --output /dev/null --write-out '%{http_code}\n' http://127.0.0.1/__log_test__ 404Replace the URL with the scheme/host/port routed to Nginx when 127.0.0.1 is not a valid listener.
- Confirm the test request appears in the access log destination.
$ sudo tail --lines 200 /var/log/nginx/access.log | grep --fixed-strings "__log_test__" | tail --lines 1 127.0.0.1 - - [14/Dec/2025:09:12:44 +0000] "GET /__log_test__ HTTP/1.1" 404 153 "-" "curl/8.4.0"
Replace /var/log/nginx/access.log with the access_log path identified above when different.
- Tail the error log destination to confirm where runtime failures are recorded.
$ sudo tail --lines 50 /var/log/nginx/error.log 2025/12/14 09:09:17 [warn] 1234#1234: *987 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/1/23/0000001234 while reading upstream, client: 203.0.113.10, server: example.com, request: "GET /largefile.iso HTTP/1.1", upstream: "http://127.0.0.1:8080/largefile.iso", host: "example.com" ##### snipped #####
Replace /var/log/nginx/error.log with the error_log destination when different.
- Query the systemd journal when error_log points to stderr or syslog:....
$ sudo journalctl --unit nginx --no-pager --lines 50 Dec 14 09:09:17 host nginx[1234]: 2025/12/14 09:09:17 [warn] 1234#1234: *987 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/1/23/0000001234 while reading upstream ##### snipped #####
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
Comment anonymously. Login not required.
