Dammika Prasad struck two decisive blows before Muttiah Muralitharan completed a 10-wicket haul to kill off Bangladesh's hopes of an unlikely record run chase as Sri Lanka won the first Test by 107 runs on Wednesday.
Set a world record 521-run victory target, the hosts were all out for 413 in their second innings a little over an hour after the lunch break on the fifth and final day.
They home side were on course for a stunning victory when they went to lunch on 373-6 needing a further 148 runs with Shakib Al Hasan and Mushfiqur Rahim set fair at the crease on 82 and 40 respectively.
However, Prasad ended their 111-run seventh wicket stand when Shakib dragged a short and wide delivery onto his stumps just four short of a maiden Test century.
His Test-best score and six-wicket haul were enough to earn him the man of the match award but he would have readily swapped the honour in favour of a Bangladesh victory.
Shakib was dismissed with the score on 403-7, already the home side's best fourth innings total and easily surpassing the 285-5 they accumulated against Zimbabwe in 2005.
Prasad soon forced Mashrafe Mortaza to edge a catch behind for two before Muralitharan ended the resistance of Rahim, caught by Tillakaratne Dilshan at midwicket for 61, to take his match tally to 10 wickets for a record 22nd time.
Mahbubul Alam was the last man to depart, his run out for two completing a dismal collapse for the hosts, who lost their last four wickets for the addition of just 10 runs.
Bangladesh's brave but ultimately futile tilt at victory means the highest fourth innings run chase remains the 418-7 scored set by the West Indies in their three-wicket defeat of Australia at St. John's in 2003.
Earlier in the morning, skipper Mohammad Ashraful gave Bangladesh a very good platform with his fifth Test century after resuming on 70
Ashraful batted elegantly, reaching his fourth century against Sri Lanka by driving Chaminda Vaas exquisitely over long on for a boundary shortly before he was trapped lbw for 101 by the same bowler.
The dismissal brought to an end his 112-run sixth wicket stand with Shakib.
Bangladesh added 119 runs in 34 overs in the session after starting the day on 254-5.
The hosts were dismissed for 178 runs in the first innings in response to Sri Lanka's 293. Sri Lanka declared their second innings on 405-6.
The two-Test series moves on to Chittagong, where the second match will start on Saturday.