Cox struck on the half hour and Mackie scored three minutes before half-time to send Leicester crashing to their first home defeat of the season.
It was Forest's first win over City in the last seven meetings between the sides, but the Foxes had only themselves to blame after spurning several good chances, including a 69th-minute penalty by David Nugent.
Leicester made one enforced change, with Paul Konchesky returning from injury to replace striker Chris Wood away on international duty for New Zealand. The versatile Jeff Schlupp switched from left-back to play up front.
Forest had three changes from the side beaten by Blackpool a week ago as Andy Reid, Jamie Paterson and Simon Cox were brought in at the expense of Eric Lichaj, Darius Henderson and Djamal Abdoun.
The Foxes dominated a fast and furious first half but still found themselves two goals down because of some poor finishing and sloppy defending.
The pace of Anthony Knockaert and Lloyd Dyer troubled Forest early on but Marcin Wasilewski was booked in the seventh minute for a bad challenge on Jack Hobbs.
A few minutes later Knockaert was also yellow carded for complaining when referee Lee Mason failed to book Jamaal Lascelles for a foul on Schlupp.
But in the 12th minute, a free-kick by Knockaert should have brought a goal only for Nugent to see his header brilliantly saved by Karl Darlow.
Three minutes later the French winger produced more trickery to set up Dyer but he fired into the side netting.
The Foxes continued to waste chances with Nugent guilty again in the 26th minute, this time putting a free header from Knockaert's free-kick over the bar.
And in the 30th minute City were punished as Forest went ahead in their first meaningful attack.
Paterson cut in from the right and although his shot was blocked City failed to clear the rebound and Cox scored from close range.
It was a real blow for City and worse followed in the 42nd minute.
Henri Lansbury forced a good save out of Kasper Schmeichel but from the corner the Foxes again failed to clear their lines and Jamie Mackie pounced to put Forest two up against the run of play.
It looked an uphill battle for the Foxes to preserve their unbeaten home record and the early signs in the second half suggested Forest were looking to tighten up even more.
City brought on Jamie Vardy for Dyer in the 60th minute but there were no signs of the Foxes breaking through.
Seven minutes later manager Nigel Pearson made two more substitutions replacing Dyer and Schlupp with Dean Hammond and Gary Taylor-Fletcher.
Then in the 69th minute Leicester were handed a gilt-edged chance to get back in the game.
David Vaughan sent Danny Drinkwater toppling just inside the penalty but Nugent, who had scored six times from the spot this season, sent his shot high and wide.