Fulham striker Aleksandar Mitrovic scored a dramatic late winner as Serbia booked their place at next year's World Cup and condemned Portugal to the play-offs.
Hosts Portugal only needed a draw to qualify and looked to have done enough, with Renato Sanches' opener cancelled out by Dusan Tadic's equaliser.
Mitrovic, who started the game on the bench, was sent on at half-time but Portugal were wise to his threat and kept him largely quiet.
However, the home side let their concentration slip in the final seconds and Mitrovic pulled away from his marker to meet Tadic's deep ball and send a downward header into the back of the net.
The goal prompted wild celebrations on the bench and on the pitch from the Serbia players and staff while the Portuguese team stood in disbelief with the home crowd silenced.
There were wild celebrations from the away side after the late winnerSerbia finish top of Group A with 20 points, three more than Portugal, whose hopes of playing in Qatar next year rest on two rounds of play-offs in March.
The defeat also ended Portugal's unbroken winning run in home World Cup qualifiers which had stretched back to October 2013.
It had looked like being a long night for the visitors after they fell behind inside just two minutes when Sanches finished confidently after Bernardo Silva had won possession.
But Serbia did not let their heads drop and deservedly equalised when Rui Patricio failed to keep out Tadic's shot, which crept over the line.
Cristiano Ronaldo, himself familiar with scoring late goals with Manchester United this season, was quiet and came closest with a free-kick in the first half.
Instead it was Mitrovic who provided the drama in the closing stages as his header secured a famous win for Serbia.
Cristiano Ronaldo must wait until March next year to find out if he will be playing at next year's World CupLine-ups
Portugal
Formation 4-3-3
1Rui Patrício
20Cancelo6José Fonte4Rúben Dias5Tavares Mendes
16Renato Sanches13Danilo8João Moutinho
10Bernardo Silva7Cristiano Ronaldo21Jota
1Rui Patrício20CanceloBooked at 8mins6José Fonte4Rúben Dias5Tavares Mendes16Renato SanchesBooked at 67minsSubstituted forNevesat 84'minutes13DaniloSubstituted forAndré Silvaat 90+2'minutes8João MoutinhoBooked at 61minsSubstituted forAlves Palhinha Gonçalvesat 64'minutes10Bernardo SilvaSubstituted forBruno Fernandesat 64'minutes7Cristiano Ronaldo21JotaSubstituted forSequeiraat 83'minutesSubstitutes
2Nélson Semedo3Dalot9André Silva11Bruno Fernandes12Malheiro de Sá14William Carvalho15da Conceição Leão17Gonçalo Guedes18Neves19Alves Palhinha Gonçalves22Meireles Costa23SequeiraSerbia
Formation 3-5-1-1
12Rajkovic
4Milenkovic21Veljkovic2Pavlovic
14Zivkovic16Lukic8Gudelj20Milinkovic-Savic17Kostic
10Tadic
18Vlahovic
12Rajkovic4MilenkovicBooked at 70mins21VeljkovicSubstituted forSpajicat 65'minutes2PavlovicBooked at 66mins14ZivkovicSubstituted forRadonjicat 69'minutes16Lukic8GudeljBooked at 13minsSubstituted forMitrovicat 45'minutesBooked at 90mins20Milinkovic-Savic17KosticSubstituted forJovicat 89'minutes10Tadic18VlahovicSubstitutes
1Dmitrovic3Mladenovic5Terzic6Maksimovic7Radonjic9Mitrovic11Jovic13Mitrovic15Spajic19Racic22Grujic23Milinkovic-SavicLive Text
Match ends, Portugal 1, Serbia 2.
Second Half ends, Portugal 1, Serbia 2.
Corner, Serbia. Conceded by Bruno Fernandes.
Attempt missed. Cristiano Ronaldo (Portugal) left footed shot from outside the box is too high. Assisted by João Cancelo.
Substitution, Portugal. André Silva replaces Danilo Pereira.
Aleksandar Mitrovic (Serbia) is shown the yellow card for excessive celebration.
Goal! Portugal 1, Serbia 2. Aleksandar Mitrovic (Serbia) header from the centre of the box to the top left corner. Assisted by Dusan Tadic with a cross following a corner.
Corner, Serbia. Conceded by Danilo Pereira.
Attempt saved. João Palhinha (Portugal) header from the right side of the box is saved in the top centre of the goal. Assisted by Bruno Fernandes with a cross.
Substitution, Serbia. Luka Jovic replaces Filip Kostic.
Corner, Portugal. Conceded by Uros Spajic.
Substitution, Portugal. Rúben Neves replaces Renato Sanches.
Substitution, Portugal. João Félix replaces Diogo Jota.
Attempt missed. Aleksandar Mitrovic (Serbia) header from the centre of the box misses to the right. Assisted by Filip Kostic with a cross.
Corner, Serbia. Conceded by João Palhinha.
Dusan Vlahovic (Serbia) wins a free kick on the left wing.
Foul by João Cancelo (Portugal).
Corner, Serbia. Conceded by Nuno Mendes.
Foul by Sergej Milinkovic-Savic (Serbia).
Renato Sanches (Portugal) wins a free kick in the attacking half.