India needed 11 runs in the last over with three wickets in hand to surpass Sri Lanka's total of 257-8 but they ended on 252-9 following a tight over from veteran left-arm spinner Sanath Jayasuriya on Sunday.
Jayasuriya conceded just five in the eventful over, which also saw well-set Mahendra Dhoni (48) fall to a superb running catch by Farveez Maharoof and Anil Kumble run-out coming back for a second run.
Sri Lanka lead 1-0 in the four-match series after the opening game was abandoned due to rain in Kolkata.
India were strongly placed at 129-2 following a 100-run stand between Sourav Ganguly (62) and Sachin Tendulkar (54) before losing their way against Sri Lanka's spin-pace combination.
This was Ganguly's third half-century in four matches since returning to the one-day side in January after a 16-month gap. He hit one six and six fours in his 79-ball knock.
Leg-spinner Malinga Bandara swung the match in Sri Lanka's favour when he removed Tendulkar and Virender Sehwag to reduce the hosts to 169-5. He received valuable support from paceman Maharoof, who finished with three wickets.
Tendulkar was stumped after hitting nine fours in his 61-ball knock, while Sehwag was caught behind for 19 in his last match to catch the selectors' eye ahead of next month's World Cup in the Caribbean.
Sehwag was dropped against the West Indies in a recent home series following his poor form on the South African tour.
India will name their 15-man squad on Monday for cricket's biggest one-day tournament, which opens on March 13.
The hosts' hopes then depended on Dhoni, who was bowled off a no-ball from paceman Lasith Malinga before he had scored. He brought India close to victory before falling in the last over.
The morning session belonged to man-of-the-match Sangakkara, whose century helped the tourists recover from early blows to post a respectable total.
India, struggling to field 11 fit players, did well after putting Sri Lanka in to bat when pacemen Munaf Patel and Shathakumaran Sreesanth bagged two wickets apiece to reduce the tourists to 58-4 on a lively pitch.
But Sangakkara came to his team's rescue, steadying the innings in a 108-run stand for the fifth wicket with Tillakaratne Dilshan (56).
He reached his century in style, swinging veteran leg-spinner Kumble for his third six. His 127-ball knock contained four sixes and 11 fours.
The 29-year-old Sangakkara offered a difficult chance on 91, when Patel dropped a return catch but the Sri Lankan smashed the next ball for four.
Patel eventually finished with 4-49, his best in one-day internationals.
The left-handed Sangakkara received support from Dilshan, who batted sensibly for his eighth half-century before being bowled by off-spinner Harbhajan Singh.
But there was no stopping Sangakkara, who continued to dominate the Indian attack with a wide range of shots. He put on 61 for the seventh wicket with Maharoof to help his team pass the 250-mark.