到了建文二年二月,李景隆又上了燕王一次大當。燕王故意到山西去攻大同,騙李景隆去救,李景隆去了,燕王就撤了兵。李景隆的兵,多半是南方人,空跑了大同一趟,凍死的與凍傷的極多,剩下的也疲憊不堪了。
四月,燕軍與李軍在涿州的白溝河交戰,戰了兩天,李景隆又遭慘敗,退到德州,守不住德州,後又隻得丟掉了一百萬石左右的軍糧,再退,退到濟南,燕王率軍窮追不舍。這時李景隆尚有十多萬兵,倉猝出戰,布陣未定,被燕王親自率領的精騎一衝擊,又複大敗。李景隆單騎落荒而逃。建文帝見李景隆一敗再敗,就免去他的大將軍職務,以左都督盛庸來接替他。李景隆回到朝中,許多人異常憤慨,揪著他在建文帝麵前哭訴說:“景隆出師觀望,內懷二心,不把他殺掉,怎麼對得起祖宗,怎能激勵將士?”但是建文帝毫無問罪之意,李景隆也就安然無事。濟南在盛庸和山東布政使鐵鉉的奮力防守下,被保住了。燕王把軍隊撤回北平,暫作休整。
盛庸在十二月大勝燕軍於東昌(山東聊城),斬燕王的第一號勇將張玉。次年(建文三年)三月,盛庸再戰燕軍於保定的夾河,大勝。燕王親自以十幾名騎兵斷後,盛庸不敢殺他,原因是建文帝有旨,不許“使朕負殺叔父之名”。接著,兩軍又展開大戰,盛軍慘遭失敗,退回德州。
兩個月以後,叛將李遠帶了若幹騎兵,冒充盛軍,穿過山東,在江蘇沛縣放火燒掉盛軍在運河的糧船。七月間忠於朝廷的平安(姓平名安)率領一萬名騎兵,由真定乘虛直搗北平,在距離北平五十裏的平村,與燕將劉江交戰,不幸戰敗,退回真定。大同的守將房昭,帶兵進入紫荊關,屯紮在易州水西寨,也在九月間被燕王攻破。遼東守將楊文,進入山海關,圍攻永平,被劉江趕走。
至此時為止,燕王雖然勝多敗少,但所得的城池僅永平、大寧、保定等地,其他的都是得而複失,不能鞏固,將士也戰死了好幾萬人。而南軍人數眾多,分布各處要地。馬皇後麵對這種形勢,燕王不禁歎息道:“頻年用兵,何時可止?要麼就臨江決一死戰,不再返顧北麵。”正當燕王為局勢悵歎之時,偏偏有若幹奉使在外的宦官,因招搖納賄而被建文帝下旨逮捕,他們逃到北平,向燕王投降,把京師與南方各省的空虛情形向燕王報告,於是燕王便在建文四年率軍大舉南下。
燕王避實就虛,不攻盛庸所守的德州與鐵鉉所守的濟南,而經由東阿、東平、汶上、兗州、沛縣,直向徐州。盛庸撤軍,退守淮河。南軍大將平安在燕王的後麵追蹤,於四月間追到(安徽)靈璧縣西南的齊眉山,先勝後敗,被擄。五月,燕兵渡淮,盛庸戰敗;六月,戰於浦子口,又敗。盛庸改守長江,都督僉事陳瑄帶了江上的水軍降燕,盛庸在高資港作最後一次抵抗,仍一敗塗地。建文帝見燕軍銳不可當,忙派人議和,燕王根本不予理睬,驅兵直逼南京城下。當時燕王的弟弟穀王與李景隆負責守金川門,燕兵一到,就開門迎降,京師告破。
燕兵進京後,宮中起火,建文帝不知去向。朱棣立即下令緊閉宮門、城門,大搜數日,務須生要見其人,死要見其屍。但連搜多日,毫無結果。宮中盛傳建文帝和馬皇後死於大火之中,朱棣命將骨灰撿出,“用天子禮”葬之。
燕王攻入南京之後不久,在群臣的擁戴下登上皇帝位,宣布以明年為永樂元年,他就是明朝曆史上的成祖皇帝。前後三年之久的皇族內部爭奪帝位的戰爭,終於以朱棣的勝利而告結束。