The game was heading for a 1-1 draw when Brugge put together a slick passing move which ended with Ruud Vormer crossing to leave the unmarked De Ketelaere with a simple finish.
Zenit is one of the few European clubs allowed to play in front of thousands of fans amid the coronavirus pandemic. Fans wore masks and generally followed social distancing rules.
The attendance Tuesday was given as nearly 16,700, just below 25% of capacity at the Gazprom Arena — which is set to be the largest of any home team in the Champions League this week. Still, that support wasn't enough for the Russian champion to win.
Emmanuel Bonaventure Dennis gave Brugge the lead in the 63rd minute after keeping the ball in play on the right touchline and feeding it into the box for De Ketalaere to hit a shot blocked on the line by Yaroslav Rakitskyy. Dennis reacted quickly to knock in the rebound.
U.S. national team goalkeeper Ethan Horvath, replacing Simon Mignolet for Brugge after Mignolet was diagnosed with the coronavirus, was credited with an own goal for Zenit’s leveler but could do little about it. Dejan Lovren’s fierce shot from well outside the box cracked against the post and bounced in off the back of the diving Horvath.
Zenit had enough chances to win the game convincingly, but Vyacheslav Karavaev skewed a shot narrowly wide shortly after Brugge's opener and Sebastian Driussi scooped the ball over the bar with only Horvath to beat. The U.S. keeper showed good reactions to push away Artyom Dzyuba's shot in the 79th.
It was only the second win for Brugge in the Belgian champion's last 19 Champions League games, not counting qualifiers.
In the other Group F game, Lazio scored two early goals in a convincing 3-1 win over Borussia Dortmund.