iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
The reliable way to find Nginx logs is to inspect the configuration that is actually running. The active access_log and error_log directives choose the destination, format, and severity; package defaults are only conventions. Start with nginx -T, identify the directives for the affected server or location, then correlate one access-log line with error-log entries from the same request and time window.
What Nginx access and error logs tell you
Nginx produces two different kinds of records:
- Access logs record completed requests. They normally contain the client address, request line, response status, response size, referrer, user agent, and any additional variables selected by the configured
log_format. - Error logs record processing problems and diagnostic messages. They can identify permission failures, missing files, refused connections, upstream timeouts, TLS problems, and configuration-load errors that an HTTP status alone cannot explain.
An access entry answers “what response did Nginx return, and how long did processing take?” An error entry helps answer “why did it return that response?” A reverse-proxy investigation usually needs both.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Find the active log destinations first
Inspect the complete running configuration
Use the configuration Nginx can load, rather than guessing a distribution-specific path:
sudo nginx -T | less
Search the output for every access_log and error_log. Pay particular attention to the server block serving the hostname and to any more-specific location block. A virtual host can write to a different file from the global HTTP setting, and a location-level directive can replace an inherited setting.
#1 Best Overall
If the command reports a permissions or syntax problem, resolve that first. You need to inspect the configuration that the installed binary can parse; an old sample file or an unused include does not describe the active service.
Check compiled-in path conventions
When a path is not obvious, inspect the build options:
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →sudo nginx -V 2>&1
Look for --error-log-path= and --http-log-path=. These options show the build-time defaults, but an explicit directive in the configuration takes precedence. The generic Nginx module defaults are logs/error.log and logs/access.log combined; relative paths are resolved under the build prefix.
Know the common package locations
| Environment | Common convention | Qualification |
|---|---|---|
| RHEL-based, Debian, and Ubuntu packages | /var/log/nginx/error.log/var/log/nginx/access.log |
These are common package paths, not guarantees. Confirm with nginx -T. |
| FreeBSD packages | /usr/local/var/log/nginx/error.log |
A common FreeBSD convention; an explicit directive may point elsewhere. |
| Container images | Often standard files or a link to /dev/stderr |
Inspect the image configuration and the container runtime’s logs. A host-side file may not exist. |
Watch the files while reproducing a request
Once the configuration gives you exact paths, follow them in separate terminals:
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
Replace the examples with the paths shown by your configuration. In a container, use the runtime’s log command when Nginx writes to standard error instead of a file.
Rank #2
Understand where each logging directive applies
access_log: destination and format
The access_log directive selects a file, standard error, or (where supported by the configuration) another destination and associates the entries with a named format. The format is defined separately by log_format. If no custom format is selected, the documented combined example includes:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →- client address;
- authenticated user, when present;
- local time;
- request line;
- final HTTP status;
- response bytes;
- referrer; and
- user agent.
Do not parse a line using assumptions from another server. Two Nginx installations can use different fields, quoting, delimiters, or formats. Read the log_format definition in the active configuration before writing a parser or deciding that a field is missing.
error_log: destination and severity threshold
error_log accepts a file, stderr, or a syslog destination and can specify a severity threshold. The directive is valid in the main, http, stream, server, and location contexts.
Thresholds are inclusive toward more serious messages. With a warn threshold, Nginx records warn, error, crit, alert, and emerg messages, but not lower-severity informational or debug output. A lower-level directive overrides an inherited setting. If multiple error_log directives are configured at the same level, a message can be written to each configured destination; otherwise it is written once to the closest applicable log.
Why a file you expect may stay empty
- The request is handled by another
serverblock selected by its host name or listen address. - A specific
locationhas its own logging directive. - The destination is
stderror syslog rather than a file. - The configured severity threshold excludes the message you expect.
- The process cannot write the file, or log rotation changed the path and the worker has not been reopened.
- The request has not completed yet, so its access entry has not been emitted.
Read an access-log line field by field
Find the outcome
$status is the final HTTP status Nginx sent for the request. A 404 means the resulting response was “not found”; it does not by itself prove that a file was absent. The response might have been generated by Nginx, an upstream application, an internal redirect, or a custom error handler.
$body_bytes_sent and $bytes_sent report response volume according to their respective variable definitions. Use the variable present in your configured format and remember that headers and body are accounted for differently.
Measure total Nginx request time
$request_time measures total request processing time in seconds, from the first bytes received until the final response processing completes. It is the quickest way to find slow requests, but it does not identify which phase consumed the time.
Separate upstream delays
For proxied or FastCGI traffic, add these variables to a custom format or inspect them if they are already logged:
| Variable | What it isolates | How to interpret it |
|---|---|---|
$upstream_connect_time |
Time to establish a connection to the upstream | A high value points toward network reachability, connection limits, or an overloaded upstream accepting connections slowly. |
$upstream_header_time |
Time until the upstream response headers arrive | A high value after a normal connect time usually indicates application or upstream processing delay. |
$upstream_response_time |
Time to receive the complete upstream response | The difference from header time can indicate a slow response body or slow upstream transfer. |
Also log the upstream address and upstream status when diagnosing proxy failures. Multiple upstream attempts can produce comma-separated values, so compare positions across related upstream variables rather than treating a list as one measurement.
Account for buffering and compression
Access logging can be buffered and flushed according to the configured buffer and flush settings. A line may therefore appear later than the request completion. Rotated logs may be compressed; the Nginx module documentation notes that compressed blocks can be read with zcat, for example:
Rank #4
zcat /var/log/nginx/access.log.2.gz | less
Use the rotation naming and compression policy configured on your host; do not assume that the newest numerical suffix contains the newest request.
Read an error-log entry in context
Start with timestamp and process details
An error entry normally gives a timestamp, severity, process identifier, and descriptive text. It may also include the client address, server name, request line, upstream address, and the operating-system error text. Record the exact time, host, method, and URI before searching; broad searches often mix unrelated virtual hosts.
Recognize common diagnostic patterns
- Connection refused: Nginx reached the upstream address but no service accepted the connection, or a local firewall/socket policy rejected it. Check that the upstream process is listening on the configured address and port.
- Permission denied: The worker could not read a static file, traverse a directory, access a certificate, or connect to a protected socket. Check ownership, mode bits, parent-directory traversal, and mandatory access controls.
- No such file or directory: The resolved root, alias, script path, socket, or certificate path does not exist. Confirm the path after variable expansion and check deployment symlinks.
- Upstream timed out: The upstream did not complete the expected operation within the configured timeout. Use upstream timing fields and inspect the application or database rather than increasing the timeout blindly.
- TLS or configuration-load failure: The error text identifies the certificate, protocol, syntax, or included file that failed. A reload that does not pass configuration validation will leave the previous configuration running.
The precise message and its context matter more than the status code. A 502 can result from a refused connection, an invalid upstream response, or a timeout; each requires a different fix.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsA repeatable workflow for 404, 502, and slow requests
- Confirm the active configuration. Run
sudo nginx -Tand identify the exactaccess_loganderror_logdirectives for the affected host and URI. - Reproduce one request. Note the UTC or local timestamp used by the log, host name, method, URI, and expected status. Use a single request first so correlation is unambiguous.
- Locate its access entry. Read the fields defined by the selected
log_format, including$status,$request_time, and any upstream variables. - Search the same time window in the error log. Match the request, client, process, upstream, and operating-system text rather than searching only for “502” or “404.”
- Check for a more specific block. Re-read the matching
serverandlocationsections for overridden roots, proxies, logging destinations, or thresholds. - Validate the proposed correction. After editing, run the configuration test appropriate to your installation, reload only after it passes, and reproduce the same request. Verify that the new access and error entries show the intended result.
Investigating a 404
Compare the request URI with the selected root or alias, the location match, and any internal redirect. If the error log says a file is missing, verify the resolved filesystem path and permissions. If no file error appears, the 404 may have been generated by an upstream application or custom error handler; the access status alone cannot distinguish those cases.
Investigating a 502
Use the error entry to distinguish refusal, timeout, or malformed upstream response. Then compare the upstream address and status in the access record with $upstream_connect_time, $upstream_header_time, and $upstream_response_time. A fast refusal is different from a long header wait, and neither is fixed by changing the same setting.
Investigating latency
Sort or filter access records by $request_time. For each slow request, compare connect, header, and response timings. A high total time with low upstream timings can indicate client transmission, response buffering, or Nginx-side processing; a high header time points more directly at upstream work.
When ordinary logging is not enough
Verify debug support before enabling it
Debug logging is disabled by default and requires a debug-capable Nginx build. Check the build information first:
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 matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11sudo nginx -V 2>&1
Only when the binary supports debug logging should you use an error_log directive with the debug threshold in the narrowest practical context. Generate one controlled reproduction, collect the relevant entries, then restore the normal threshold. Debug output is substantially more verbose and can expose request details, consume storage, and make other events harder to find.
Prefer a temporary, narrow scope
Place diagnostic logging at the affected server or location when possible instead of enabling it globally. Confirm the destination has sufficient space and that rotation can handle the temporary increase. Remove or reduce the setting after the problem is understood.
Compare logging setups before changing one
For a migration, incident review, or server comparison, document these properties for each setup:
| Axis | Questions to answer |
|---|---|
| Destination | File, standard error, or syslog? Is the destination visible from the host, container, or service manager? |
| Scope | Is the directive in main, http, server, or location? Which lower-level block overrides it? |
| Severity | What threshold is active, and will it include the event you need? |
| Format and fields | Which log_format is selected? Are status, request time, upstream address, and upstream timings present? |
| Buffering and compression | When are lines flushed, and how are rotated files compressed or named? |
| Retention and rotation | Which component rotates logs, how long are they retained, and how are open files reopened? |
| Upstream visibility | Can you distinguish connection, first-byte, and full-response delays? |
Quick command checklist
sudo nginx -T | less— print the complete effective configuration and find active logging directives.sudo nginx -V 2>&1— inspect build options, including compiled-in log paths and debug capability.sudo tail -f /path/from/nginx-T/access.log— watch completed requests.sudo tail -f /path/from/nginx-T/error.log— watch warnings and errors.zcat /path/to/rotated.log.gz | less— inspect a compressed rotated log.
Replace every illustrative path with the destination shown by the active configuration. If Nginx logs to stderr, read the container or service-manager log stream instead of creating an assumed file.
Recommended Free Tools
Quick Recap
Practical interpretation rules
- Trust the active directive over a distribution convention or a tutorial’s sample path.
- Interpret a line according to its configured format, not the documented combined example unless that format is actually selected.
- Use the final status as an outcome, then use error text and upstream fields to find the cause.
- Keep timestamps, host names, URIs, process identifiers, and upstream addresses together when correlating records.
- Remember that access logging occurs after request processing and may be delayed by buffering.
- Treat debug logging as a short, targeted escalation that needs a debug-capable build.
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.

