Hamilton had been in a class of one at the Sochi Autodrom and appeared on course to claim the 80th pole of his career after topping the time sheets in the first two phases of qualifying.
But the British driver, three tenths up on his team-mate in the opening sector on his final hot run, ran wide at the right-handed seventh turn and was forced to abort his lap.
Hamilton finished 0.145 seconds down on Bottas while Sebastian Vettel, 40 points adrift in the championship race, qualified a distant third.
Vettel desperately needs to beat Hamilton today to stop the British driver from running away with the title. However, the 31-year-old German will now have to navigate his way past not one, but two Mercedes cars at a track where overtaking is notoriously difficult, to stand any chance of victory.
Like Mercedes, Ferrari have brought a revised package with them to Russia, yet Vettel was never in contention here, finishing an eye-watering six tenths off the pace. His team-mate Kimi Raikkonen finished fourth.
“It was a nice lap,” Finnish driver Bottas said. “I think Lewis aborted his, but it feels good. I am really happy, for sure, but it is only the first step of this weekend and it is a long run from the start line to turn one.”
Hamilton, magnanimous in defeat, paid tribute to his team-mate.
“Valtteri did a better job,” he said. “It was intense naturally, but my last two laps were not special and you can’t always get it right. At least we are still in the fight for tomorrow.”
Vettel started on pole last year, but was beaten after Bottas got the jump on him on the opening lap.
“It was important to get as close as possible to them,” he said. “It should have been a lot closer, but not enough to be a threat. I just spoke to Valtteri and reminded him about what happened last year. Hopefully we can turn it around.”
The second phase of qualifying was rendered completely meaningless with five drivers, the number of cars eliminated from Q2, not bothering to post a time. The Red Bull duo of Max Verstappen and Daniel Ricciardo and the Toro Rosso of Pierre Gasly already knew they would be sent to the back of the grid due to a series of engine penalties.
Renault meanwhile, took the tactical decision not to run either Carlos Sainz and Nico Hulkenberg to ensure they would start outside the top ten, in 11th and 12th, and enjoy a free tyre choice for the race.
Brendon Hartley, who finished 16th, and Fernando Alonso, one place lower, will also take grid sanctions for exceeding the number of permitted engine parts, meaning a quarter of the 20-strong field have been penalised.
Elsewhere, Kevin Magnussen qualified an impressive fifth for Haas ahead of Force India’s Esteban Ocon. Local driver Sergey Sirotkin qualified only 18th while his Williams team-mate Lance Stroll, bound for Force India next year, finished last.