The Reds missed an opportunity to go second in the Championship following a surprise defeat at struggling Scunthorpe in midweek but Billy Davies' side, aided by Norwich drawing at Leeds, made no such mistake this time round and replaced the Bluebirds behind leaders QPR.
Defender Wes Morgan put Forest ahead with his first goal of the season just after the half-hour mark at the City Ground.
Peter Whittingham equalised from the penalty spot in the 64th minute but Earnshaw won it for Forest three minutes later to extend the Reds' proud unbeaten home run to 35 league games - a record which stretches back to September 2009.
Davies made one change as Nathan Tyson dropped down to the bench to be replaced by Paul Anderson.
Aaron Ramsey missed out against the club he was on loan at last month as Cardiff made two enforced changes.
The Arsenal midfielder failed a late fitness test along with Michael Chopra so Whittingham and Jon Parkin, making only his second start since signing from Preston in January, came into the team.
Cardiff created a couple of early chances. Jay Bothroyd's shot hit Lee Camp's outstretched foot and looped over the crossbar.
Then, with Camp beaten, Paul Konchesky came to the Forest keeper's rescue as he cleared Craig Bellamy's shot off the line.
Camp, who was this week granted permission by FIFA to represent Northern Ireland, continued to keep Cardiff at bay with parrying saves to deny Bothroyd and Bellamy midway through the first half.
At the other end, Earnshaw flicked a header over when he really should have at least worked Tom Heaton in the Cardiff goal.
It was against the run of play when Forest scored in the 32nd minute. Lewis McGugan crossed from the left-hand side and Morgan powered the ball past Heaton from six yards out.
It was almost 2-0 five minutes later. Anderson's cutback from the byline was straight into McGugan's path but the shot from Forest's leading scorer clipped the top of the crossbar.
McGugan again came close to scoring his 12th goal of the season early in the second half but his free-kick curled just past the top corner.
Camp was called into action once more on the hour to tip Seyi Olofinjana's shot over the crossbar.
Cardiff equalised after Chris Gunter was adjudged to have handled Bothroyd's cross. Whittingham sent Camp the wrong way from the penalty spot for his 50th club goal.
Substitute Jay Emmanuel-Thomas had a chance to put Cardiff ahead but found Camp in the way once more.
The Welsh side were only level for three minutes as Earnshaw pounced on Anderson's pass and slid the ball under Heaton from 12 yards out.
Tyson wasted a glorious chance to give Forest a two-goal cushion with 10 minutes remaining.
Cardiff were left three against one as Tyson attacked down the right but instead of squaring a simple pass to McGugan, the winger greedily opted to shoot from an acute angle and missed the target.
However, Cardiff could not make Tyson pay for his misjudgement and Whittingham put their final chance harmlessly wide.