Java debugging
How to read Java stack traces and find the root cause
A Java stack trace looks intimidating because it records every method involved in a failure. You rarely need to read every line. With the right order, you can reduce a long trace to the exception, the true cause, and the first line of code you should inspect.
What a Java stack trace tells you
A stack trace is a snapshot of the active method calls when an exception occurred. It normally contains an exception type, an explanatory message, a list of stack frames, and sometimes one or more nested causes.
java.lang.NullPointerException: Cannot invoke "Customer.getId()"
because "customer" is null
at com.example.order.OrderService.createOrder(OrderService.java:87)
at com.example.order.OrderController.create(OrderController.java:42)
at org.springframework.web.servlet.FrameworkServlet.doPost(...)
Caused by: com.example.customer.CustomerNotFoundException: Customer 1042 was not found
at com.example.customer.CustomerClient.find(CustomerClient.java:61)In this example, the most useful facts are the deepest Caused by message and the first frame belonging to the application. Framework frames provide context, but they are rarely the first place to edit code.
Step 1: read the exception type and message
Start with the first line. The exception type identifies the category of failure, while the message describes what went wrong in this specific case.
NullPointerExceptionCode used a reference that was null.
IllegalArgumentExceptionA method received a value it considers invalid.
ConnectExceptionA network connection to another service could not be established.
SQLExceptionA database query, update, connection, or constraint failed.
Do not stop at the type. A detailed message such as customer is null is much more actionable than the generic phrase “null pointer.”
Step 2: follow the “Caused by” chain
Java applications often catch a low-level exception and wrap it in a higher-level one. Each Caused by: section reveals the exception underneath the previous layer.
Read the chain from the bottom upward. The deepest cause is usually closest to the original failure. For example, a Spring BeanCreationException may ultimately be caused by a missing environment variable, invalid database password, or duplicate bean definition.
Confirm it using nearby application frames, request data, configuration, and the behavior you can reproduce.
Step 3: find the first frame from your code
Every line beginning with at is a stack frame. It shows the class, method, source file, and line number that were active during the failure.
at com.example.order.OrderService.createOrder(OrderService.java:87) └──────── class ────────┘ └─ method ─┘ └── file and line ──┘
Skip past Java, Spring, servlet, proxy, and reflection frames until you find your organization's package name. Open that file at the reported line, then inspect the values used there and the calls immediately before it.
Step 4: inspect the failing line in context
The numbered line is where Java noticed the failure, not always where the bad value originated. Read several lines above it and trace each input backward.
- Which object, argument, or return value failed?
- Where was that value created or retrieved?
- Could a database query or API legitimately return no result?
- Does one request path skip initialization or validation?
- Did configuration differ between working and failing environments?
A guard clause can prevent a crash, but it may hide the real defect. Fix the point where invalid or missing data first becomes possible when that behavior violates the application contract.
Step 5: separate the root cause from secondary errors
One failure can generate many later messages: transaction rollbacks, broken response writes, retry failures, or shutdown warnings. Sort entries by timestamp and request or trace ID. The earliest relevant error is often more useful than the loudest final message.
When multiple services are involved, follow the same correlation ID across the gateway, API, downstream service, and database logs. This creates a timeline instead of treating every error as a separate incident.
Common Spring Boot stack traces
BeanCreationExceptionRead its deepest cause for missing configuration, dependency failures, or code executed during bean initialization.
UnsatisfiedDependencyExceptionCheck which constructor or field dependency Spring could not provide, then inspect qualifiers, profiles, and component scanning.
HttpMessageNotReadableExceptionThe request body could not be parsed. Compare JSON syntax, field types, date formats, and required values with the request model.
DataIntegrityViolationExceptionA database constraint may have rejected the operation. Read the nested SQL exception for the actual constraint or column.
ResourceAccessExceptionA network call failed. Look for nested timeout, DNS, TLS, or connection-refused details.
What “... more” and suppressed exceptions mean
Java shortens repeated frames using text such as ... 24 more. It means those frames are identical to frames already printed above; it does not mean that information is missing.
A Suppressed: section records another exception that happened while Java was handling the main one—often when closing a file, stream, or connection. Investigate it when the primary cause does not fully explain the failure, but keep the main exception chain as your first path.
A reliable root-cause workflow
- Capture the complete trace with the timestamp and correlation ID.
- Read the exception type and specific message.
- Move to the deepest relevant
Caused bysection. - Find the first stack frame from your application package.
- Open the reported file and inspect the line in context.
- Trace the failing value back to its source.
- Reproduce with sanitized input in a safe environment.
- Add or update a test that proves the correction.
Share logs safely
Before sending a trace to a teammate or putting it into any analysis tool, remove credentials and personal or production data. Stack traces can include request headers, URLs, database details, filenames, email addresses, tokens, and internal hostnames.
Remove passwords, API keys, cookies, access tokens, authorization headers, customer records, and confidential business data. Rotate a secret if it was exposed.
Explain your stack trace
Paste a sanitized Java or Spring trace into Log Explainer to identify the error pattern, likely causes, important lines, and the next debugging steps. The analysis runs locally in your browser.
Open Log Explainer