Manchester City are spluttering at the start of the Champions League and needed a late David Silva winner to beat Hoffenheim. A scrappy display followed the opening defeat to Lyon and while Pep Guardiola pointed to his side’s spirit and three points he will be concerned.

This was Hoffenheim’s home debut in the competition and Julian Nagelsmann’s men can be proud of knocking heralded opponents out of their rhythm.

Vincent Kompany, the City captain, said: “It was a tough away game, a physical game. They were committing an awful lot of bodies forward and because we don’t defend in that many numbers we had to be cautious.

“We dominated. We had possession, a lot of chances. Credit to us for reacting like we did and scoring in the dying minutes. It’s a fantastic result because every away game in the Champions League is so hard to get three points from and it was the only way to put the Lyon game behind us.”

City endured a nightmare start, going behind inside 60 seconds owing to a sleep-walking defence. When Ishak Belfodil ran on to a slick pass, Aymeric Laporte, the left-back for the night, was left trailing and the Hoffenheim forward beat Ederson expertly. “It felt like it was offside but these things happen,” Kompany said.

Guardiola was left stony-faced and while his side tried to absorb the shock Joelinton went close to putting his side 2-0 up. Luckily for City his shot was hit straight into Ederson’s arms.

City were behind for only seven minutes, though, and the equaliser came straight from the Guardiola playbook: Leroy Sané got in behind the defence and Sergio Agüero poked home.

Pavel Kaderabak, Hoffenheim’s left wing-back, was proving a danger. The 26-year-old’s pace was too much even for Kyle Walker and he outstripped the right-back and might have won a penalty when going to ground.

Guardiola had selected as strong an XI as he could, which meant Agüero at centre-forward, despite a heel problem. The match was the first of five finals the City manager spoke of during the buildup but Hoffenheim lost at the weekend and are 11th in the Bundesliga, leaving City the firm favourites to win.

By the half-hour point City had established dominance as they camped deep in Hoffenheim territory and peppered the area with crosses and corners. Yet the tension was illustrated by Damir Skomina giving Guardiola a lecture, the referee apparently unhappy at the manager stepping out of his technical area.

Agüero’s flailing at a volley was the closest City had come for a while to forcing a second goal, despite their superiority. Moments later he displayed his skills more expertly when curling a chip that Oliver Baumann only just tipped away.

When Hoffenheim managed to push forward they usually threatened, which will have worried Guardiola. Belfodil skimmed a ball that Ederson did well to collect, then Joelinton hit a fierce shot the City goalkeeper beat away.

The half closed as it began: open, and with a chance on goal. This time it was for City via a raking clearance from Ederson into Agüero’s path. He cut infield and let fly a shot that was always rising.

Belfodil nearly scored again when the second half started in a mirror image of his opener but this time he flashed a shot across goal.

The lack of a rhythm in City’s play was shown up by a free-kick that had Nicolás Otamendi heading clumsily and the resulting Ilkay Gündogan corner hit in too low. Meanwhile, Ederson went close to being embarrassed when he charged out to clear and missed the ball.

With 25 minutes left Guardiola took off Otamendi for John Stones, who moved into midfield as the shape changed to a back three.

Considering their callowness Hoffenheim were performing admirably. Yet when Sané was pulled down by Baumann it was a mystery why the referee – much to Guardiola’s fury – did not award a penalty.

The manager refused to talk about the incident later for fear of sanction but Kompany said: “We don’t want to complain too much. Unfortunately it’s been a trend but if that trend reverses in six months we will take the hard moments now.”

By the close Hoffenheim were hanging on as City pressed for a winner that came when David Silva ghosted into the area to stab beyond Baumann after robbing Stefan Posch when the defender tried to chest down Bernardo Silva’s cross.