Stephen Eustaquio struck in the 92nd minute, firing past a helpless Ronwen Williams to secure Canada’s 1-0 victory just as the match seemed destined for extra-time.
Canada will now face the winner of the last-32 tie between the Netherlands and Morocco, in the Round of 16 on Saturday, 4 July.
Bafana boss Hugo Broos made one change from the side that beat South Korea in their final group game, with Teboho Mokoena returning from his one-match suspension in place of Thalente Mbatha.
Jesse Marsch made four changes to the team that lost to Switzerland, with Moise Bombito, Eustaquio, Tani Oluwaseyi and Liam Millar replacing Luc De Fougerolles, Mathieu Choiniere, Ali Ahmed and Cyle Larin.
There were some early nerves on display from South Africa as they looked to settle int the game, while a superb cross-field ball from Relebohile Mofokeng looked to release Oswin Appollis, only for Alistair Johnston to make an excellent clearing header.
READ: Preview: Bafana Bafana Set for Historic World Cup Round of 32 Clash Against Co-Hosts Canada
Maxime Crepeau then had to get down low to his right to keep out a Mokoena effort from the edge of the area after a fine piece of attacking play opened up the Canadian defence.
Canada’s quick attacking play was also causing problems for the South African defence and Williams was grateful to see a dangerous Richie Laryea cross blocked.
Mbekezeli Mbokazi got across well to stop Millar from getting a shot away as he raced into the box in the 15th minute.
Yaya Sithole then made a goal-saving tackle as Jonathan David looked to pull the trigger following another swift counter-attack, with the Canadian striker then dragging his effort wide from the resulting corner.
Derek Cornelius should have put Canada ahead in the 22nd minute with a free header from a whipped-in Eustaquio free-kick, but he failed to make any meaningful contact just a few yards from goal, allowing Williams to gather comfortably.
South Africa were seeing far more of the ball than they had against South Korea but were struggling to feed Evidence Makgopa, with a long Mokoena pass on the half-hour mark comfortably collected by Crepeau.
There was a nervy moment soon after when Mokoena gifted possession to Nathan Saliba, but Millar could only fire straight at Williams.
Appollis made good progress down the left flank but was denied by an outstanding tackle from Bombito just as he looked to deliver his cross.
Oluwaseyi then headed over from a 42nd-minute corner while Mbokazi had to be alert to clear inside the penalty area with Johnston lurking.
There was then a huge sigh of relief for Bafana from the resulting corner as first Aubrey Modiba brilliantly cleared a Bombito header off the line before Khuliso Mudau blocked the follow-up effort. Williams then denied Laryea with a brave save before the ball was finally hacked clear.
If that wasn’t enough drama for an action-packed first half, the opening 45 minutes ended with a VAR check for a potential penalty after Maseko challenged Laryea, with Mudau also making contact from behind. The referee originally denied Canada a penalty and the VAR agreed.
Broos introduced Thalente Mbatha at half-time in place of Mofokeng, who had struggled to contain his man down the right flank. Canada though threatened first after the restart, but Millar was off target with a difficult effort from a tight angle.
After a lull in attacking intent, Bafana moved forward with purpose as they sliced through the Canadian midfield, but a final ball was lacking and Crepeau calmly collected Modiba’s delivery at the far post.
Niko Sigur and Luc De Fougerolles replaced Nathan Saliba and Bombito just before the hour mark as Marsch looked to freshen up his side.
South Africa’s best chance arrived in the 62nd minute after a slick passing move, but Appollis’ sweetly struck effort from outside the area curled narrowly wide of the top corner.
Mbokazi then produced another vital intervention to steer the ball away from the onrushing Jonathan David after Williams had parried Oluwaseyi’s shot. It proved to be Oluwaseyi’s final involvement as he was replaced by Promise David, while Jacob Shaffelburg came on for Millar.
A promising South African attack ended with Sithole curling an ambitious effort well over the crossbar, while the Canadian supporters were buoyed by the introduction of Alphonso Davies for Tajon Buchanan with 13 minutes remaining — Davies’ first appearance of the tournament.
Promise David was inches wide in the 76th minute after being picked out by his namesake Jonathan David, with Davies involved in the build-up. Williams was then forced into another good save at his near post to keep out Jonathan David.
South Africa were struggling to get out of their own half as the match entered its closing stages, with Canada sensing a late winner.
Appollis forced Crepeau into a smart save with one of Bafana’s rare efforts on target before Broos made a double substitution, introducing Iqraam Rayners for Makgopa and Tapelo Moremi for Maseko.
Rayners looked set to race through on goal with a minute of normal time remaining, but De Fougerolles recovered superbly to clear the danger.
Five minutes of stoppage time were added and, with both teams seemingly destined for extra time, South Africa’s hearts were broken when Eustaquio latched onto a headed clearance on the edge of the area and drilled a superb finish beyond Williams.
There was no time for a response as Canada booked their place in the Round of 16, while South Africa’s 2026 FIFA World Cup dream came to a heartbreaking end.