Suppose main() is frame 1 and the method that ultimately throws the exception is frame 10. Java prints a trace like this:
message for 4
4
3
2
1
message for 7
7
6
5
4
message for 10
10
9
8
7
This feels backwards because the most relevant failure appears at the bottom, and the repeated frames make the trace harder to follow. Wouldn't it be clearer to print the deepest cause first, followed by the exceptions that wrapped it?
For example:
message for 10
10
9
8
message for 7
7
6
5
message for 4
4
3
2
1
That ordering seems to show the failure unfolding from its source back to the original caller, while also avoiding repeated frames. Why was the conventional format designed the other way around?
2 Answers
The repeated-looking frame numbers are there to show how the exception chain connects. Java compares each cause's stack with the stack of the exception that wraps it and omits the shared tail, usually reporting something like “... N more.” In a real trace, those entries aren't meant to be independent duplicate calls; they identify the point where one exception's path overlaps with another's. The convention prioritizes the exception being handled and keeps the surrounding caller context easy to locate.
The trace starts with the exception you actually caught and printed. If code at frame 4 catches an IllegalArgumentException, printing that exception should describe that exception first: frames 4 through 1. A deeper exception, such as the one at frame 10, is its cause and is printed afterward. Reversing the order could make it look as though the deeper exception was the one your code caught, even when it was only part of the cause chain.

That explains the cause-chain relationship, although it doesn't necessarily make the output intuitive to someone looking for the original failure. Reading the deepest cause first would be a reasonable alternative, but it would change the long-established meaning of the first exception shown.