В начале лета хан выступил в поход. Ахмату удалось собрать большое войско: «со царем вся Орда, и братаничь его Каисым, да 6 сынов царевых, и бесчисленное множество Татар с ними» (80, 327). Ордынцы медленно шли к литовским рубежам, чтобы через земли Казимира выйти к Угре. Желая скрыть от противника свои истинные намерения, хан отправил большой отряд к Кашире, вражеская конница разорила селения на берегах реки Беспуты и быстро отступила (79, 199).
Стояние на реке Угре. Миниатюра из Лицевого летописного свода
В Москве были своевременно извещены о продвижении степняков, горькие уроки 1472 г. пошли на пользу Ивану Васильевичу и его воеводам. Разобравшись в обстановке и оценив размер угрозы, великий князь приказал выдвигать полки к Оке, чтобы на этом рубеже остановить нашествие. «Пояс Богородицы» вновь должен был защитить Русь. В начале лета на Оку пришли рати Андрея Вологодского и Василия Верейского, 8 июня на защиту южных границ повел полки Иван Иванович Молодой, сын и наследник великого князя. Полки Андрея расположились в окрестностях Тарусы, преградив путь орде на этом направлении, войска Ивана Молодого прикрыли берег Оки в районе Серпухова. Ахмату удалось временно ввести в заблуждение великого князя о своих планах идти на Угру. Когда в Москве стало известно, что орда подошла к Дону, Иван III покинул столицу и во главе войск прибыл в Коломну. Случилось это 23 июля. Но поскольку Ахмат продолжал вести войско на запад, великому князю и его воеводам стал ясен замысел противника. Иван Васильевич приказал Андрею Вологодскому и сыну Ивану оставить позиции под Тарусой и Серпуховом, срочно идти к Калуге и занять рубеж на реке Угре (80, 327). На переправах и бродах ратники вбили колья, на берегу установили пушки. Орда уже шла по землям Казимира, миновала Мценск, Любутск, Одоев и подошла к Воротынску, где хан стал ждать своего литовского союзника. Однако король и сам не пришел и войск не прислал. Выполняя договоренности с Иваном III, крымский хан Менгли-Гирей вторгся в принадлежащую Казимиру область Подолии и опустошил регион. В этой ситуации король не рискнул идти на помощь Ахмату. Не дождавшись Казимира, хан повел орду к Угре.
Дальнейшие события получают у исследователей различную трактовку. Согласно Львовской летописи, Иван Васильевич приказал сжечь Каширу, покинул Коломну и в сопровождении князя Федора Палецкого «побежа на Москву» (72, 345). Сыну Ивану и воеводе Даниилу Холмскому государь приказал прибыть в столицу по первому зову. В Москве Иван Васильевич объявился 30 сентября, его приезд вызвал волнение среди посадского люда, «граждане роптаху на великого князя» (72, 345), обвиняли его в трусости. Выразил неудовольствие и ростовский архиепископ Вассиан. Разгневанный святитель заявил Ивану III, что «вся кровь на тебя падет христианская, потому что ты, выдав их, бежишь прочь, бой татарам не дав и не бившись с ними. Почему боишься смерти? Не бессмертен ты, человек, смертен, а до срока нет смерти ни человеку, ни птице, ни зверю. А отдай воинов под мое начало, неужели я, старый, спрячу лицо от татар?» (23, 435). Опасаясь народного недовольства, великий князь жил не в столице, а в Красном сельце, откуда и рассылал приказы. Население Дмитрова было выведено в Переславль-Залесский, великая княгиня Софья с детьми и государственной казной уехала на Белоозеро. Иван Молодой проигнорировал приказ родителя прибыть в Москву и остался на Угре: «Подобает мне здесь умереть, а не к отцу ехать» (23, 435). Поведение государя в эти судьбоносные дни летописец напрямую связывал с происками его советников, Ивана Ощеры и Григория Мамона: «Это были бояре богатые у великого князя, они не думали за христиан стоять и с татарами биться, а думали бежать прочь, а христиан выдать, обрекая тем на безвременную смерть бьющихся в бою, помня только о своем большом богатстве, женах и детях» (23, 435). Иван Васильевич не хотел покидать Красное сельцо и ехать на Угру, государь «едва умолен бысть» (72, 346) архиепископом Вассианом. Впрочем, Иван III мог появиться в Москве и по другой причине, поскольку в это время в столицу прибыли послы от его мятежных братьев. На переговорах удалось достигнуть компромисса, что было бы невозможно в отсутствие великого князя. Иван Васильевич получил благословение высшего духовенства, 3 октября покинул Москву и выехал на театр боевых действий. Великокняжеская ставка расположилась в Кременце (в наши дни село Кременское), откуда до Угры было около 60 км. Вместе с государем остались только его телохранители, всех приведенных из Москвы ратников Иван III отправил на Угру. Согласно свидетельству Вологодско-Пермской летописи, великокняжеская рать занимала берега Угры и Оки на протяжении 60 верст (81, 264).
8 октября к Угре подошли главные силы ордынцев, Ахмат не стал медлить и сразу отправил войска на захват бродов и переправ. Ханская конница устремилась на противоположный берег реки, но была встречена залпами пушек и пищалей, попала под обстрел лучников. Вбитые в дно колья затрудняли движение всадников, не давали степнякам прорваться к берегу. Нукеры ломали прикрывавший переправы палисад, не обращая внимания на потери, рвались на левый берег Угры. Навстречу ордынцам устремились русские ратники, на переправах завязались ожесточенные рукопашные схватки. Ахмат пытался нащупать слабое место в обороне противника, нанося удары на всем протяжении фронта великокняжеской рати. Основной натиск орды пришелся на полки Андрея Вологодского и Ивана Молодого. Четыре дня русские отбивали атаки степняков, понеся большие потери, Ахмат убедился в невозможности прорвать вражескую оборону и приказал войскам отойти от реки на две версты. Хан «ста в Лузе» и распустил воинов по владениям Казимира в поисках фуража и съестных припасов. Попытка Ивана III начать переговоры успеха не имела, хан решил вновь испытать военное счастье. Ордынцы стали форсировать Угру у Опакова Городища, где река извилиста и мелководна. Князья и воеводы стянули к месту возможного прорыва значительные силы и успешно отразили наступление. Отказавшись от лобовых атак, Ахмат стал ждать, когда Угра покроется льдом и конница сможет беспрепятственно перейти на вражеский берег. Летопись донесла до нас зловещие слова хана Большой Орды: «даст Бог зиму на вас, и реки все станут, ино много дорог будет на Русь» (72, 346). Но всё пошло не так, как надеялся Ахмат.
Зима наступила рано, ударили морозы, река стала замерзать. Удивительно, но данное обстоятельство испугало как русских, так и ордынцев: «бысть страх на обоих, едини других бояться» (79, 200). Опасения Ивана III и его соратников были вполне обоснованы, теперь ханская конница по льду Угры могла обойти русские позиции или прорвать растянутый вдоль реки фронт великокняжеской рати. Поэтому решение великого князя оставить берег Угры и собрать всю рать в Кременце выглядит стратегически правильным и обоснованным. Но затем государь приказал оставить Кременец и отступить к Боровску, «говоря, что «на этих полях будем с ними сражаться», а на самом деле слушая злых людей – сребролюбцев, богатых и брюхатых, предателей христианских и угодников басурманских, которые говорят: «Беги, не можешь с ними стать на бой». Сам Дьявол их устами говорил, тот, кто некогда вошел в змея и прельстил Адама и Еву» (38, 383). В эти судьбоносные дни Москва была охвачена страхом, люди боялись появления ордынской конницы под стенами столицы.
Страхи Ахмата были вызваны обстоятельствами иного свойства: «бяху бо Татарове нагы и босы, ободралися» (72, 346). Добывать продовольствие ордынцам становилось всё труднее, их кони отощали, воины оголодали, начались болезни. Большое сражение с московской ратью таило опасность для измученного долгим стоянием ханского войска. Поэтому Ахмат приказал отступать. Согласно Вологодско-Пермской летописи, орда стала уходить от Угры 8 ноября, в канун Михайлова дня, по свидетельству Московского летописного свода конца XV века, это произошло 11 ноября. Можно предположить, что 8 числа начался отход от реки главных сил, а 11 ушли отряды прикрытия. Всего во владениях Казимира ордынцы провели шесть недель и разорили 12 городов (81, 273). Ахмат был зол на короля за обман и приказал воинам на обратном пути грабить земли неверного союзника. Царевич Амуртоза попытался воевать на правом берегу Оки, но бежал при приближении полков Андрея Углицкого, Бориса Волоцкого и Андрея Вологодского.
Есть другая версия, объясняющая поспешное бегство Ахмата в степь. Когда орда шла к Угре, на военном совете у великого князя было предложено отправить по Волге судовую рать и «юрты Батыевы разорити» (71, 8). Речь шла о нападении на Сарай, столицу Большой Орды. Хан увел в поход на Русь практически всех воинов, защищать ордынские тылы было некому. И если рейд увенчается успехом, Ахмат получит сокрушительный удар: «дело добре, иже польза бысть ему велика» (71, 8). Великий князь согласился с доводами воевод и приказал готовить судовую рать. Возглавили поход воевода Василий Ноздреватый-Звенигородский и царевич Нур-Девлет, вместе с русскими ратниками против ордынцев шли воевать служилые татары. Великокняжеское войско спустилось на ладьях в низовья Волги и подвергло юрт Ахмата дикому погрому. Сопротивления не было, поскольку в орде остались лишь «женеск пол, стар и млад» (71, 8). Разорив вражеские земли, Василий Ноздреватый и Нур-Девлет с большим полоном и богатой добычей ушли на Русь. Когда об этом набеге стало известно Ахмату, хан был вынужден отступить от Угры. Данная информация присутствует только в «Истории о Казанском ханстве», летописцы её проигнорировали, приписав избавление Руси от Орды Божьему промыслу, а не стратегическим планам Ивана III. Хотя данный рассказ органично вписывается в общий контекст событий и не противоречит летописным свидетельствам.
28 ноября Иван Васильевич вместе с сыном, братьями и воеводами вернулся в столицу, противостояние с Ахматом закончилось убедительной победой московского князя. В отличие от Куликовской битвы, добыта она была малой кровью: «