Real Madrid booked their place in the Champions League last 16 by burying Manchester City's faint hopes with a 1-1 draw at the Etihad Stadium.
Sergio Aguero sent Spain goalkeeper Iker Casillas the wrong way from the penalty spot on 73 minutes to bring the home side level after Karim Benzema had given Jose Mourinho's team the lead on 10 minutes.
Real had to see out the final 17 minutes with 10 men after Alvaro Arbeloa was sent off for collecting a second booking for the foul on Aguero that led to the penalty.
He had been booked earlier for a late challenge on Aguero by Italian referee Gianluca Rocchi, whose decisions lacked consistency throughout the evening. It was later claimed that Rocchi had bungled the first booking with Alonso making the challenge that saw Arbeloa booked.
City huffed and puffed, but could not break down Real, who join Borussia Dortmund in progressing to the last 16 after the German champions' 4-1 thumping of Ajax in Amsterdam.
Dortmund will win Group D whatever happens in the final round of matches. The Bundesliga side have 11 points from five matches with Real on eight. Ajax are on four with City at the foot of the group on three points.
City need to overcome Dortmund in Germany and hope that Real down Ajax to finish third in the section and secure Europa League football next year. That looks an unlikely prospect unless Dortmund field a team of stooges in the closing match of the section.
But that is for another night as the inquest begins into why City, one of the wealthiest clubs in the world, have again come up woefully short in Europe's premier club competition.
This was a match between the English and Spanish champions, but Real were much slicker in possession and always seemed aware of their responsibilities with City appearing disjointed for large swathes of the first period.
England goalkeeper Joe Hart conceded after the match that his side had not been good enough to qualify for the next stage of the tournament, and he has to look at his role in the goal that led to Real's opener.
City appeared to nod off when Angel Di Maria threw a hopeful ball into the middle that enabled Benzema an easy task to finish from close range with Hart and Maicon caught ball watching.
Real should have moved further ahead before half-time as chances came and went with City toiling to cope with the movement of the visiting side.
Cristiano Ronaldo beat the offside trap and Hart with a lob on 15 minutes only for Matija Nastasic to race back to scramble off his line.
Sami Khedira - who had already knocked a couple of Ronaldo passes wide - burst through a posse of home players on 23 minutes, but could not lift the ball over Hart as he raced out to produce a brave block.
City's best moments of the first period ended with Maicon prodding wide from an Aguero return ball while David Silva picked out Edin Dzeko on 30 minutes only for the big forward to fluff his lines off balance as he tried to direct a volley goalwards.
City appeared to be more sure of themselves in the second period with Casillas alert to nudge the ball away from Aguero after he had combined well with Silva.
Aguero had a glorious chance to level on 63 minutes when the ball broke to him kindly from Maicon's deflected cross, but Casillas produced an astonishing stop from what appeared unmissable range.
Aguero had his moment when Arbeloa was sent off for a late challenge in the area. The Argentine sent the ball to Casillas's left as the goalkeeper dived right.
Despite a frantic surge to find the winning goal, Real held on comfortably enough despite their one-man disadvantage.
MAN OF THE MATCH
Xabi Alonso - Real Madrid: A calm head at the heart of the midfield area for the visiting side.
Manchester City: Hart 5, Maicon 6, Zabaleta 6, Kompany 6, Nastasic 6, Kolarov 5, Yaya Toure 6, Silva 7, Nasri 5, Dzeko 5, Aguero 7. Subs: Milner 6, Javi Garcia 5, Tevez 6.
Real Madrid: Casillas 7, Arbeloa, Pepe 6, Ramos 6, Coentrao 6, Khedira 6, Xabi Alonso 7, Di Maria, Modric 5, Ronaldo 7, Benzema 7. Subs: Varane 6, Albiol 6, Callejon 6.