A star-studded Racing side that finished second in the regular season and lost the European Champions Cup final to Leinster was the clear favourite in the semi-final contest at Groupama Stadium.
But Castres, the champion in 2013, benefitted from Racing's ill-discipline before holding out with 14 men for most of the closing stages after Julien Dumora's sin-binning.
Racing had a try ruled out in each half but, despite outscoring the underdogs two tries to one, was unable to find a killer blow.
Castres struck first when Maama Vaipulu crashed over from a maul. Benjamin Urdapilleta kicked the extras and then added a three-pointer to stretch the early lead to 10.
Louis Dupichot saw a try chalked off for a Racing infringement in the build-up, but the Paris side did respond when Juan Imhoff showed electric pace from Remi Tales's offload to dot down.
Dupichot then broke the lines to score Racing's second, only for ill-discipline to creep into its game, allowing Urdapilleta to kick two penalties either side of a yellow card for Ben Tameifuna, moving Castres back in front.
Racing could have been punished more for that sin-bin offence, but Urdapilleta and Rory Kockott each missed from the tee.
Racing scrum half Teddy Iribaren thought he had punished those missed kicks when he broke after a lineout to score under the posts, only for the play to be called back for a forward pass.
Urdapilleta then gave Castres some breathing space by once again splitting the posts, although Dumora's yellow for a high tackle on Imhoff with 14 minutes remaining saw their numbers depleted with the lead at just five.
Racing peppered the line and had a series of close-range scrums in a dramatic finish, but Castres held firm for a fine win.