Sri Lanka overcame a late wobble to battle past New Zealand by five wickets and book their place in the World Cup final.
The co-hosts were coasting to victory while Tillakaratne Dilshan (73) was continuing his prolific form in a 120-run stand with Kumar Sangakkara (54).
Dilshan deposed England's Jonathan Trott as the tournament's top runscorer in what appeared a straightforward chase of 217 all out under lights at the Premadasa Stadium.
But the second-wicket pair were both among the batsmen to go as Sri Lanka stumbled and stalled from 160 for one in the 33rd over to 185 for five in the 43rd.
Some strong nerves were therefore required from the late middle order to haul them through - with a flattering 13 balls to spare - to an all-subcontinental showpiece decider in Mumbai on Saturday, against either Pakistan or India.
It will be a third, and second successive, final for today's winners - while New Zealand have now appeared in six semis yet have still not managed to take the next step.
Sri Lanka restricted their opponents to a below-par total, despite Scott Styris' first half-century of the campaign.
Styris (57) shared an important stand of 77 for the fourth wicket with Ross Taylor to raise New Zealand hopes after they won the toss.
But the Kiwis lost momentum at crucial stages, and their last six wickets fell for 25 runs as they were bowled out in the 49th over.
On the same strip, England's 229 for six had proved emphatically inadequate in last weekend's quarter-final.
Dilshan played largely against type, more subdued than his habitual tempo, but still finished with 10 fours and a six from 93 balls - to his captain's seven and one from 79.
A wonderful diving catch by Jesse Ryder at point off an Upul Tharanga square-drive at Tim Southee brought New Zealand's first wicket.
But Dilshan and Sangakkara knew crease occupation and strike rotation would suffice - and try as New Zealand might, they did not quite have enough runs to defend.
There was nonetheless a sizeable flutter in the capacity home crowd when three more wickets fell for only nine runs.
The Southee-Ryder combination struck again to spoil Dilshan's fun; then Mahela Jayawardene was lbw on the forward-defence to Daniel Vettori for a single, and Sangakkara upper-cut Andy McKay straight to third-man.
Chamara Silva chopped Southee (three for 57) on to his stumps, but Thilan Samaraweera and Angelo Mathews kept their cool to get Sri Lanka over the line.
New Zealand's top three had each got started, but little more.
Brendon McCullum was bowled by a Rangana Herath arm ball, attempting to repeat the dose after slog-sweeping the same bowler for six in his previous over.
Muttiah Muralitharan got one to turn and bounce to have Ryder caught behind cutting - and Lasith Malinga (three for 55) returned, after just one over with the new ball, to york Martin Guptill with a trademark inswinger.
Styris' first task was to keep out a clutch of devilish Malinga yorkers, and he survived to drive well against both pace and spin in a 77-ball innings which contained five fours.
But when Taylor pulled a rare bad ball from Ajantha Mendis straight to deep midwicket in the 40th over, the Kiwis began to subside.
Master off-spinner Muralitharan marked his final international delivery in his native country with a big off-break to have Styris lbw on the back foot, and then Mendis (three for 35) clicked into gear.