Home › Guides › How to read a stack trace

How to read a stack trace

Direct answer: read it in three passes: the exception line (what happened), the top application frame (where in your code it happened), then — for chained traces — the deepest cause. Skip the framework frames in the middle; they are plumbing. Python prints the exception LAST; Java prints it first with Caused by chains below.

Group traces from your log

Drop a log file here — or click to choose one. Files are read in slices on this device (designed for logs up to ~500 MB); nothing is uploaded.

Anatomy, with a Java example

java.lang.NullPointerException: Cannot invoke "Item.getPrice()" because "item" is null is the exception line: class + message. Below it, frames run from the throw site upward: at shop.orders.OrderService.process(OrderService.java:142) is the top application frame — the line of your code to open first. Frames below (OrderController.create, then Spring/Tomcat frames) show how execution got there. The file:line is a gift: open it before forming theories.

Caused by: read to the bottom of the chain

Java wraps exceptions: an IllegalStateException "Order total is negative" may wrap the IllegalArgumentException that actually originated it. Each Caused by: goes one level closer to the origin, so the root cause is the last one — and grouping tools fingerprint on the OUTER exception plus top frame, because that pair is what the log's header reports and what repeats.

Python is printed backwards (on purpose)

A Python traceback starts with Traceback (most recent call last):, lists frames from the outermost call inward, and ends with the exception line — KeyError: 'user_881'. The frame that matters is the LAST File frame (the raise site). Chained exceptions print two tracebacks joined by "During handling of the above exception…" — read the SECOND traceback's exception for what finally escaped, and the first for the original failure it was handling.

Go panics

A panic prints the panic line, a [signal …] line, then goroutine stacks: function names with their file:line pairs beneath. The first function in the first goroutine is the crash site. "Invalid memory address or nil pointer dereference" is the Go null-pointer — the frame tells you which value, in which function, was nil. Grouping a whole file of these (plus every other format) is what the Error Grouper automates; the method is in how to group repeated errors in a log.

Frequently asked questions

Which line of a stack trace matters most?

Two: the exception line (what happened — the last line of a Python traceback, the first exception line in Java) and the top application frame (where in YOUR code it happened). Framework frames in the middle are plumbing. A Caused by: chain inverts the reading: the root cause is the deepest Caused by, not the outermost exception.

What is the "top application frame"?

The first frame that belongs to your code rather than a library or the runtime — in Java, the first at-line with your package; in Python, typically the deepest File frame in your modules. Grouping tools key on it because the same exception from a different throw site is a different bug with a different fix.

The trace is truncated with "... 27 more". Am I missing the cause?

No — that marker (Java) means the remaining frames are identical to the enclosing exception’s frames, which are printed above. It is deduplication, not missing data. What you should hunt for is the LAST Caused by in the chain: each level wraps the one below, and the innermost is closest to the origin.