Anthony Lozano’s smart first-half finish gave the visitors their first win against Real in almost 30 years.
Zinedine Zidane’s side dominated possession but only managed two shots on target against a resilient Cadiz.
Luka Jovic had the ball in the net but Karim Benzema had strayed offside from Marcelo’s cross earlier in the move.
Benzema struck the bar with a fierce effort from outside the box with 10 minutes to go but the hosts could not extend their 15-game unbeaten run in the competition.
Cadiz, however, continued their dream start after returning to the Spanish top flight for the first time in 14 years this season.
Lozano clipped the ball over goalkeeper Thibaut Courtois from Alvaro Negredo’s assist after 16 minutes to score what proved to be the winner.
Negredo headed wide in the first half and the 35-year-old had another effort cleared off the line by Sergio Ramos, who later had to be substituted because of injury.
Cadiz, runners-up to Huesca last season, had a chance for a second after half an hour when Jose Mari found Lozano and his low shot was pushed away by Courtois at the near post.
Real Madrid pushed for a leveller late on but the visitors were able to hold on for their first victory against their opponents in La Liga since March 1991.
Zidane’s side must now regroup for their opening Champions League match against Shakhtar Donetsk on Wednesday, before visiting Barcelona on Saturday.