Rubber Duck Debugging / 4 of 5 / 1 views
How to Read an Android Stack Trace
How to Read an Android Stack Trace Without Panicking
The most common reaction to seeing a long stack trace for the first time is to panic, scroll straight to the top, and hope the answer is right there. But a stack trace actually has a structure that, once understood, is fairly systematic to read.
Anatomy of a Stack Trace
Take this example:
FATAL EXCEPTION: main
Process: com.example.app, PID: 8421
java.lang.NullPointerException: Attempt to read from field 'String User.name' on a null object reference
at com.example.app.ui.DetailActivity.showData(DetailActivity.kt:87)
at com.example.app.ui.DetailActivity.onCreate(DetailActivity.kt:42)
at android.app.Activity.performCreate(Activity.java:8000)
Caused by: java.lang.NullPointerException
at com.example.app.data.UserRepository.getUser(UserRepository.kt:55)A few key parts:
- FATAL EXCEPTION: main — the crash happened on the main thread. If it's not
main, a different thread name shows up here, which is an important clue if the issue actually lives in a background thread. - Exception type —
NullPointerException,IndexOutOfBoundsException,IllegalStateException, and so on. This alone narrows down the possible causes. - The message right after the exception type — in the example above, the message is already fairly clear: the
namefield on aUserobject was read while the object was null. Many developers skip past this, even though it often already answers most of the question. - The
at ...lines — this is the call stack, the order of function calls from outermost to innermost, read top to bottom. - Caused by — the most commonly overlooked part, and also the most important one. When a
Caused byshows up, it means the exception above it is just a "symptom," while the actual root cause is the exception named underCaused by.
Focus on Lines That Belong to Your Own App
Stack traces often contain plenty of lines from Android framework code (android.app.Activity, etc.) or third-party libraries. These lines matter for context, but they're rarely where the root cause actually lives. The main focus should be on lines mentioning your own app's package — in the example above, that's DetailActivity.kt:87 and UserRepository.kt:55.
A common mistake: spotting the first line that mentions a library name (ExoPlayer, Retrofit, whatever) and immediately concluding "this is a bug in the library." Often the library is just where the exception happens to explode, while the actual cause is the app calling that library with the wrong parameters.
A Case From Experience
There was once a crash whose stack trace pointed directly into an internal ExoPlayer class, and the first instinct was to blame the library version. But digging further into the Caused by section revealed the actual root cause sat in the app's own code — a MediaSource was being built with an empty URL because of a race condition between the playlist-fetching process and the player initialization process. ExoPlayer was just the component that happened to surface the symptom first, not the actual source of the problem.
The lesson: the exception type and the top line of a stack trace show you where the program stopped, not automatically why it stopped.
Questions Every Stack Trace Should Answer
What exception type is it?What's the exact error message?
Which file and line in your own app's code is involved?
Is there a "Caused by"? If so, what does it say?
What variable is the actual problem (null, wrong index, etc.)?
Why was that variable in that state to begin with?
```
That last question is the one people skip most often. Answering "the user variable was null" isn't the end of the investigation — the real question is why user was null at that point. Was the API call not finished yet? Was an intent extra never sent? We'll dig into that more in the next article on null safety debugging.
Once the stack trace and Logcat have given you evidence about where and what happened, the next step is understanding the flow that got the program there — which is what the next article, on program flow tracing, covers.