Spain were made to pay for a host of wasted chances as Ukraine inflicted their first defeat in nearly two years.
Leeds forward Rodrigo spurned two headed chances as Ukraine goalkeeper Georgi Bushchan continually frustrated the former world champions in the stadium where they won Euro 2012.
Spain had 21 shots in total but Ukraine needed just one to score in Kiev.
Substitute Viktor Tsygankov ran on to West Ham forward Andriy Yarmolenko’s pass to beat David de Gea.
The Manchester United goalkeeper was caught out of position on the counter-attack as Luis Enrique’s side lost for the first time since Croatia beat them 3-2 in November 2018.
They now lead Group A4 by just a point from both Ukraine and Germany, who drew 3-3 with Switzerland.
About 15,000 fans were allowed in to watch the Nations League game, which was dominated by Spain.
The visitors had 72% of possession and forced Bushchan into eight saves, but the Dynamo Kiev man was in unbeatable form.
Spain manager Luis Enrique: “Blaming De Gea is already wrong, it puts a lot on him. If David is blamed for a game like this, turn it off and let’s go.
“The responsibility for each goal lies with the whole team.
“We have made chances to kill them. It was a game of clear control of us, with Adama Traore we have generated chances with his overlap.
“In the end we went into panic mode. I like the attitude of the players, I like what I see.”