The running Nginx configuration—not a universal default—decides where access and error messages go. Start by printing that configuration, find the applicable access_log and error_log directives, then correlate one access entry with error messages from the same request time. On many packaged Linux installations the files are /var/log/nginx/access.log and /var/log/nginx/error.log; containers may send the same streams to standard output and standard error instead.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
This guide shows how to locate the active destinations, understand each field, investigate 404 and 502 responses, identify slow upstream requests, and escalate safely to debug logging.
As an Amazon Associate I earn from qualifying purchases.
Recommended Free Tools
What Nginx access and error logs contain
Nginx has two complementary logging streams. The access log records a request after processing finishes. It normally includes the client address, request line, final HTTP status, response size, referrer and user agent, but the exact fields come from the configured log_format. The error log records operational messages such as connection failures, permission problems, missing files, upstream timeouts and configuration or TLS errors.
These streams answer different questions. An access entry tells you what the client received and how long Nginx spent processing it. An error entry explains an internal failure or warning that may have produced that result. A 502 in the access log is an outcome; the error log usually contains the reason, such as a refused connection or an invalid response from an upstream server.
#1 Best Overall
Find the logs Nginx is actually using
Print the complete active configuration
Run the configuration test with the dump option so included files and inherited settings are visible:
sudo nginx -T | less
Search the output for every access_log and error_log. The directive closest to the affected request matters: a location setting can replace a server setting, which can replace an http setting. Do not assume that the first path you find applies to the virtual host you are troubleshooting.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallIf the command reports a syntax error, the running worker processes may still be using the last valid configuration. Fixing the syntax and reloading is a separate operation; first identify which configuration the currently running service loaded.
Check compile-time paths when a directive is not obvious
Use:
sudo nginx -V 2>&1
Inspect the output for --error-log-path= and --http-log-path=. These are build-time defaults, not guarantees. An explicit directive in the configuration takes precedence, and a package can compile different paths from another package.
Common locations by installation type
| Installation or environment | Common destination | Qualification |
|---|---|---|
| Debian or Ubuntu package | /var/log/nginx/access.log/var/log/nginx/error.log |
Typical package convention; verify the active directives. |
| RHEL-based package | /var/log/nginx/access.log/var/log/nginx/error.log |
Typical package convention; local configuration can override it. |
| FreeBSD package | /usr/local/var/log/nginx/access.log/usr/local/var/log/nginx/error.log |
Common FreeBSD location, not a universal rule. |
| Container image | Often standard output/error; sometimes /var/log/nginx/error.log links to /dev/stderr |
Read the container logs through the runtime as well as checking the image configuration. |
| Source build with no overriding directives | logs/access.log and logs/error.log |
Paths are relative to the build prefix and can differ from distribution packages. |
For a quick live view, use the path shown by the active configuration:
Rank #2
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
Replace those examples if nginx -T shows another destination, stderr, or a syslog target. The error_log directive accepts a file, stderr, or a syslog destination; access_log can likewise be configured for a file or syslog.
Understand the access log before interpreting a line
The format is configuration-defined
access_log selects both a destination and a format. The documented combined example contains the client address, authenticated user, local time, request line, status, response bytes, referrer and user agent. A site may add or remove fields, so read its log_format declaration before assigning meaning to a column.
A line that looks like this is commonly the combined format:
203.0.113.24 - - [15/Oct/2026:12:44:07 +0000] "GET /checkout HTTP/1.1" 200 18432 "https://example.test/cart" "Mozilla/5.0"
In that example, the status is 200 and the response size is 18432 bytes. The timestamp is the request’s local log time, not necessarily the client’s timezone. If your format includes quoted fields or escaped values, avoid splitting lines on spaces without accounting for the quotes.
Variables that answer common diagnostic questions
| Variable | What it tells you | How to use it |
|---|---|---|
$status |
The final HTTP status returned by Nginx. | Group requests into successful responses, redirects, client errors and server errors. |
$body_bytes_sent |
Response body bytes sent to the client. | Estimate payload size without counting all headers. |
$bytes_sent |
Total bytes sent, including response headers. | Use when total wire volume is relevant. |
$request_time |
Total request-processing time, measured from the first bytes read until the log write. | Find requests that are slow from the client’s perspective. |
$upstream_connect_time |
Time spent connecting to an upstream. | Separate network or connection establishment delays from application work. |
$upstream_header_time |
Time until the upstream response headers arrive. | Expose slow application startup or time to first byte. |
$upstream_response_time |
Time until the complete upstream response is received. | Compare upstream transfer time with total request time. |
Upstream variables can contain multiple values when Nginx tries more than one upstream server. Preserve the delimiters and order when comparing retries; a single averaged number can hide the failed first attempt.
When the line is missing or delayed
Nginx writes an access entry after request processing ends. A request that is still running will not appear until it completes or is terminated. Buffered logging can delay writes further: inspect the buffer and flush parameters on access_log when live observation does not match request timing.
Rotated files may be compressed. List the configured log directory and decompress a rotated file before searching it; the Nginx module documentation notes that compressed log blocks can be read with zcat. For example:
zcat /var/log/nginx/access.log.2.gz | less
Use the rotation tool’s naming and retention policy rather than assuming that the newest numbered file contains the newest event.
Read error logs by severity and context
Severity is a threshold
An error_log level records messages at that level and more severe levels. With a warn threshold, Nginx records warn, error, crit, alert and emerg. A lower threshold such as debug is more verbose; an emerg threshold is the least verbose.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →| Level | Typical meaning | Operational use |
|---|---|---|
debug |
Detailed internal processing. | Short diagnostic sessions only, when the binary supports it. |
info |
Informational events. | Useful during targeted investigation; potentially noisy. |
notice |
Notable normal events. | Optional operational detail. |
warn |
Something unexpected that may still allow service to continue. | Common production threshold. |
error |
A request or operation failed. | Common baseline for incident review. |
crit, alert, emerg |
Increasingly serious conditions affecting operation. | Always investigate promptly. |
Scope and inheritance change what you see
The directive can appear in main, http, stream, server or location contexts. A lower-level setting overrides an inherited one. Messages are written once to the closest applicable log unless multiple directives at the same level are configured. This explains why an error can be absent from the global file while appearing in a per-site file.
Rank #4
Each entry commonly includes a timestamp, worker process identifier, client address, server name, request, upstream information and operating-system error text. Treat those details as a correlation key, not decoration. “Connection refused,” “permission denied,” “no such file,” an upstream timeout and a TLS failure point to different remedies even when the access status is identical.
A reliable request-correlation workflow
- Confirm the loaded configuration. Run
sudo nginx -Tand identify the exactserverandlocationhandling the host and URI. Record every applicableaccess_loganderror_log. - Reproduce one request. Note the UTC or local timestamp shown by the host, the hostname, method, URI and expected status. A unique query string or a distinctive test path can make the access line easier to find.
- Watch the destination while reproducing. Use
tail -Ffor a file that may be replaced during rotation, or use the container runtime’s log command when the destination is standard error. - Read the complete access entry. Interpret columns according to the configured
log_format. Start with$statusand$request_time, then inspect request and upstream fields. - Search the same time window in the error log. Match timestamp, process ID, client, host, URI and upstream address. Allow for clock format and timezone differences between systems.
- Check for a more specific destination. Revisit nested
serverandlocationblocks if the global file has no matching entry. - Escalate only as needed. If ordinary severity does not explain the event, verify debug support with
nginx -Vbefore changing the level.
Diagnose common statuses with the logs
404 Not Found
First determine whether Nginx or an upstream application generated the 404. The access format may include upstream status variables; if it does, compare the upstream status with $status. A static-file 404 usually pairs with an error entry about a missing file and a filesystem path. Check the selected root or alias, URI-to-file mapping, and filename case. If an upstream returned the 404, inspect the application route and the URI Nginx forwarded instead of changing filesystem permissions blindly.
502 Bad Gateway
Find the matching error entry and read its exact upstream message. “Connection refused” generally means no process is listening at the configured address or a local policy rejected the connection. A timeout indicates a failure to connect or receive data within the configured limits. An invalid or prematurely closed upstream response points to the upstream process or protocol. Use the access line’s upstream address and timing fields to distinguish connection delay from application response delay, then verify the upstream service independently.
Slow reverse-proxy requests
Compare $request_time with $upstream_connect_time, $upstream_header_time and $upstream_response_time. A large connect time suggests network, DNS or listener pressure. A large header time means the application took a long time to begin responding. A response time close to the header time but a much larger total request time can indicate client upload/download time or other Nginx processing. Without these variables in the configured format, the existing logs cannot reconstruct the missing timings; add them deliberately for future requests.
Use debug logging as a controlled escalation
Debug logging is disabled by default and is not available in every binary. Before enabling it, run nginx -V and verify that the build includes debug support. If it does, set a narrowly scoped directive such as error_log /path/to/diagnostic.log debug; in the relevant context, test the configuration, reload Nginx, reproduce the problem, collect the needed lines, and restore the previous severity. A broad debug stream can grow rapidly and may expose request details, so protect the file and keep the collection window short.
sudo nginx -t
sudo nginx -s reload
Never assume a successful reload means the intended location is now logging at debug level: confirm the directive’s context and destination with nginx -T after the change.
Containers, rotation and permissions
Containers and standard streams
Container images commonly route error output to standard error, and some link /var/log/nginx/error.log to /dev/stderr. In that arrangement, host-side log collection—not a file inside the container—is the durable source. Check both the image’s Nginx configuration and the container runtime’s logs. A short-lived container can lose file logs when its writable layer is removed.
Rotation and retention
Find the rotation policy used by the operating system or your logging platform. Rotation can rename or replace a file while a long-running worker still has the old descriptor open; use the platform’s supported reload or reopen procedure and verify that new requests reach the new file. Keep retention long enough to cover incident investigation, and monitor disk usage because verbose formats and debug sessions increase volume.
Access and privacy controls
Reading logs normally requires elevated permissions because files can contain client addresses, authenticated usernames, paths, query strings and user-agent data. Grant the smallest read access needed, avoid copying sensitive entries into tickets, and protect archived and compressed files with the same controls as live logs. If a format includes credentials or tokens in query strings, change the format or upstream application so those secrets are not logged.
Compare two Nginx logging setups
When reviewing a migration or a production-versus-staging difference, compare the dimensions that affect what can be observed:
| Dimension | Questions to answer |
|---|---|
| Destination | Is output written to a file, standard error, or syslog? Who retains and searches it? |
| Scope | Are directives set globally, per HTTP service, per server, or per location? |
| Severity | What is the threshold, and does it omit warnings needed for diagnosis? |
| Format and fields | Does the access format include status, request time, upstream address and upstream timings? |
| Buffering and compression | Can entries be delayed, and how are rotated files decompressed for searches? |
| Retention and rotation | How long are logs kept, and does rotation safely reopen the destination? |
| Debug capability | Can the installed binary accept the debug level when a targeted escalation is required? |
Quick command reference
sudo nginx -T | less— print the complete loaded configuration, including included files.sudo nginx -V 2>&1— inspect build options and compiled default paths.sudo nginx -t— validate configuration syntax before a reload.sudo nginx -s reload— ask a running master process to reload a valid configuration.sudo tail -F /path/from/nginx -T— follow a file across rotation; substitute the actual path and omit the command if the destination is not a file.zcat /path/to/rotated.log.gz | less— inspect a compressed rotated log.
The decisive habit is to trust the active directives and configured fields, then correlate one timestamped access record with the nearest error entry. Default paths are useful starting points, but only the running configuration tells you where this Nginx instance is writing and what each column means.
Free tools Windows power users keep installed
One-click scans. No signup required.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




