Home › Nginx Error Log Analyzer
Nginx error log analyzer: group error.log into distinct problems
Direct answer: drop your Nginx error.log below. Its repeated failures —
connect() failed, upstream timed out, no live upstreams, SSL handshake
failures — are grouped into distinct problems, each with a count, first and last seen, and redacted samples,
ranked by severity × frequency. The values that change between occurrences (client addresses, connection
numbers, quoted requests and upstreams) are masked before lines are compared; the server name is not, so two
sites sharing one file keep separate rows. Processed locally; nothing is uploaded.
Group this log now
⚠ Raw values are visible on this screen only. Saved board data and every export stay redacted — exports never contain raw values.
Time range in file: —
This board was restored from this browser's storage — stored samples are the redacted copies by design. The raw-view toggle has no effect on restored boards.
| Severity | Problem (first sample line) | Count | First seen | Last seen |
|---|
No repeated problems — every entry in this file was seen exactly once. Check the singletons below.
Singletons — entries seen exactly once
Grouping is deterministic normalisation: timestamps, IDs, IPs and numbers are masked, then entries are matched on the masked message plus the top application frame. It groups — it does not diagnose. Check a group's samples before you act on it.
How it works
- Drop the error.log (or paste an excerpt) into the panel.
- Press Group errors. The file is processed in your browser — watch progress, cancel any time.
- Read the Triage Board: upstream failures, handshake errors and missing files as distinct problems, ranked by severity × frequency.
- Open a group to inspect its pattern and samples; export the incident report if the findings need to travel.
The bracketed word at the start of each line — [error], [warn],
[crit] — is read as the entry's severity, and severity drives the ranking together with
frequency, so a short burst of critical failures is not buried under a day of warnings.
What grouping does to an error.log
Every error.log line has the same anatomy: date, time, the bracketed level, process and connection numbers, the failure message — then, for request failures, the circumstances: client, server, request, upstream, host. The failure repeats; the circumstances never do. That split is exactly what grouping uses. These three lines are one problem wearing three sets of circumstances:
2026/11/09 06:12:01 [error] 1842#1842: *104729 connect() failed (111: Connection refused) while connecting to upstream, client: 203.0.113.7, server: shop.example.com, request: "GET /checkout HTTP/1.1", upstream: "http://127.0.0.1:3000/checkout", host: "shop.example.com"
2026/11/09 06:12:04 [error] 1842#1842: *104755 connect() failed (111: Connection refused) while connecting to upstream, client: 198.51.100.23, server: shop.example.com, request: "POST /api/orders HTTP/1.1", upstream: "http://127.0.0.1:3000/api/orders", host: "shop.example.com"
2026/11/09 07:40:19 [error] 1843#1843: *105201 connect() failed (111: Connection refused) while connecting to upstream, client: 192.0.2.44, server: shop.example.com, request: "GET /cart HTTP/1.1", upstream: "http://127.0.0.1:3000/cart", host: "shop.example.com" They come back as a single row — connect() failed while connecting to upstream, count 3, first seen 06:12:01, last seen 07:40:19. Multiply that by a busy morning and the file's thousands of lines become the handful of failures that actually need fixing: the refused upstream, the timed-out report route, the expired upstream certificate behind the SSL handshake failures.
Honest details
Missing files group by failure, not by path. The path in an open() line is a
quoted value, and quoted values are masked — so a missing favicon and a missing robots.txt count as one
"file not there" problem. The group's samples show the real paths; nothing is hidden, and the tool's
"distinguish short quoted strings" option can split them if the paths matter more than the failure on
your site.
Server names stay visible. When several sites share one error.log, the same upstream failure under two server blocks appears as two rows — deliberate: the fix, and usually the owner, differs per site, and merging them would understate each one.
Grouping is not diagnosis, and archives need opening first. The board will tell you the
upstream refused connections 800 times starting at 06:12 — not why the upstream was down. And drop the
plain text file: a rotated .gz archive has to be decompressed before it can be read here.
error.log is not access.log
The access log is the other Nginx file: one line per request, with the status it was answered with. If your question is which routes return 404 or 500, or when traffic peaks, that is Access-Log Triage — and the guide finding errors in an Nginx access log covers the route-pattern method. This page is for the file that explains why those 502s happened. Application logs from behind the upstream (Node, Python, Java and the rest) group on the Error Grouper — the same grouping, framed for stack traces.
Frequently asked questions
What is the difference between error.log and access.log?
The access log records every request — method, path, status, bytes sent — whether or not anything went wrong. The error log records what went wrong while serving them: refused upstream connections, timeouts, failed SSL handshakes, files that were not there. Questions about traffic and statuses belong to the access log; questions about failures belong here. Same server, two files, two different jobs.
Where do I find my error.log?
Wherever the error_log directive in your configuration points — that directive is the authority. On most packaged installs it is /var/log/nginx/error.log, and many setups keep a separate error log per site alongside the global one. With the official Docker image the error log is sent to stderr instead, so the same lines appear in the container log output (docker logs). If the lines start with a date, a time and a bracketed level like [error], you have the right file.
What does grouping do with upstream errors?
It separates the failure from its circumstances. The message — connect() failed, upstream timed out, no live upstreams — is the problem; the client address, connection number, request and upstream values trailing after it change with every occurrence, so they are masked before lines are compared. Eight hundred refused connections to one upstream come back as one problem with a count of 800, a first-seen and a last-seen — and the samples keep real lines (redacted) so you can see which requests were affected.
Why did two different missing files land in one group?
Because the file path in an open() line is a quoted value, and quoted values are masked before grouping — deliberately: on most sites, "favicon.ico is missing" and "robots.txt is missing" are the same operational problem (files the server expects are not there), counted once. The samples inside the group show the actual paths, so nothing is hidden — and if the paths matter more than the failure, the "distinguish short quoted strings" option above splits groups whose short quoted values differ.
Is my error.log uploaded or stored anywhere?
No. The file is read and processed in your browser; nothing is uploaded. Samples on the board and in every export are redacted by default — client IPs, addresses, tokens and passwords that happen to appear in log lines are masked in what is shown, saved and exported. You can switch the on-screen view to raw for your own screen only; exports and saved board data stay redacted regardless.