How to read Nginx and Apache error logs (with examples)
Find the error log path in your configuration, note when the problem happened, and read the first error line at that time: the level in brackets, then the message, then the client, request and upstream. Match it to the access log by time and request to see the status code visitors got.
Web servers keep two kinds of log. The access log records every request and its status code. The error log records what went wrong and why. When visitors report a 502 or a blank page, the access log tells you when and how often; the error log usually tells you what failed.
Where the logs are
Nginx: the error_log directive sets the file. The official documentation gives the default as logs/error.log, relative to where Nginx is installed, at level error. The access log defaults to logs/access.log in the "combined" format. Many Linux packages change these paths, so check the error_log and access_log lines in your configuration rather than guessing.
Apache: the ErrorLog directive sets the file. Apache's documentation says it is typically named error_log on Unix systems and error.log on Windows, and calls it "the most important log file". The access log is set with CustomLog.
On a hosting control panel, look for a section called Logs or Error logs; the host chooses where the files live.
Log levels: how serious is each line?
Nginx lists its levels in order of increasing severity: debug, info, notice, warn, error, crit, alert and emerg. Setting a level logs that level and everything more severe. With the default of error, you see error, crit, alert and emerg lines, but not warnings.
Apache uses similar level names. Its documentation adds a useful detail: in version 2.4, some "File does not exist" messages for 404s are logged at info level, so with the default warn level you will not see them in the error log. Look in the access log instead.
Anatomy of an Apache error line
Apache's documentation walks through an entry like this one (synthetic sample, fictional Northgate Store site):
[Fri Oct 09 21:14:12.902022 2026] [proxy_http:error] [pid 3570:tid 140213] [client 203.0.113.24:51022] AH01102: error reading status line from remote server 127.0.0.1:8080
In order, Apache describes:
Date and time of the message.
Module and severity: here the proxy_http module, at level error.
Process ID and thread ID of the server process that hit the problem.
Client address that made the request.
The message itself. The code starting with AH identifies the message, which makes it easy to search.
Anatomy of an Nginx error line
Nginx lines carry similar information in a different order (synthetic sample):
2026/10/09 21:14:12 [error] 2207#2207: *5521 connect() failed (111: Connection refused) while connecting to upstream, client: 203.0.113.24, server: shop.example, request: "GET /checkout HTTP/1.1", upstream: "http://127.0.0.1:8080/checkout", host: "shop.example"
Date and time, then the level in square brackets.
Process and thread IDs, joined by a hash sign.
Connection number after the asterisk, useful for grouping lines from the same request.
The message: here, Nginx could not connect to the application behind it.
Context: the client, the server name, the request line and the "upstream", which is the back-end application Nginx passes requests to.
Read the message first, then the upstream. "Connection refused" means nothing was listening at that address, so the application is probably stopped or on another port. Our guide to connection refused vs timed out explains the difference.
Matching the error log to the access log
The Nginx combined format writes each request as one line: client address, user, time, request, status code, bytes sent, referring page and browser. A 502 for the request above would look like this (synthetic):
203.0.113.24 - - [09/Oct/2026:21:14:12 -0700] "GET /checkout HTTP/1.1" 502 157 "https://shop.example/cart" "Mozilla/5.0"
To connect the two, match the time and the request path. Then count: one 502 at 2 a.m. is noise; hundreds in five minutes is an outage. For what each status code means, see our guide to HTTP status codes.
Common patterns and what they point to
Upstream connection refused: the application behind the web server is not running or is unreachable. Check whether it crashed and why, in its own log.
Upstream timed out: the application took too long. Nginx's proxy_read_timeout defaults to 60 seconds between two reads, and proxy_connect_timeout also defaults to 60 seconds. Slow database queries and overloaded servers are common causes. Raising timeouts can hide the real problem.
Permission denied: the server process cannot read a file or folder. Check ownership and permissions on the path in the message.
No such file or directory: a file the configuration points to is missing, or the path has a typo.
Too many internal redirects: the sample message in Apache's documentation blames a "probable configuration error"; rewrite rules that send requests in a loop are a common culprit.
A short routine for reading any server log
Note the time of the problem, with time zone.
Watch the error log live while you reproduce it. Apache's documentation suggests tail -f error_log on Unix systems.
Find the first error at that time, not the last. Later lines are often knock-on effects.
Read the message, then the context: client, request, upstream.
Check the upstream application's own log for the same moment.
Change one thing at a time, then reload and test.
Before sharing log lines with a host or forum, remove visitors' IP addresses, cookies and tokens. Our guide on sharing logs safely shows how.
Have the log read for you
EasyToDecode, launching soon, will take a pasted or uploaded server log, quote the lines that explain the failure, match errors to status codes, flag what is missing and suggest what to check first and what to ask your host. See how it works or join the waitlist to hear when it opens.
Questions
Where is the Nginx error log?
Wherever the error_log directive in your configuration points. The official default is logs/error.log relative to the install location, but many Linux packages use a different path.
Why don't I see 404 errors in the Apache error log?
Apache's documentation notes that in version 2.4 some "File does not exist" messages are logged at info level, which the default warn level does not record. Check the access log.
What does "upstream" mean in an Nginx error?
The back-end server or application Nginx forwards requests to. Upstream errors usually mean that application is down, slow or unreachable.
Should I just raise the timeout to fix a 504?
It may hide the symptom. Nginx's read timeout defaults to 60 seconds; if requests take longer, find out why the application is slow first.
Sources
- nginx documentation: Core functionality, error_log (checked October 10, 2026)
- nginx documentation: Module ngx_http_log_module (checked October 10, 2026)
- nginx documentation: Module ngx_http_proxy_module (checked October 10, 2026)
- Apache HTTP Server 2.4: Log Files (checked October 10, 2026)
About this guide. Prepared by the EasyToDecode editorial team. Facts were checked against the official sources listed above (last checked October 10, 2026).
How we prepare and check our guides
General information, not legal, financial or tax advice. Rules differ by state, province and territory and change over time; check the sources and, for decisions with legal or financial consequences, a qualified professional.