朱棣起兵后不久,就“拔居庸关,破怀来,执(都督)宋忠,取密云,克遵化,降永平”,扫平了北平的外围。经过朱元璋大肆杀戮功臣以后,这时,朱允炆已无将可使,只好起用幸存的老将耿炳文为大将军,率军十三万伐燕。
建文元年(1399年)八月,师至真定,于滹沱河为燕军所败,退保真定,坚守不出,“燕王知炳文老将,未易下,越三日,解围还”。朱允炆听到耿炳文军败,根据黄子澄的推荐,任李景隆为大将军取代耿炳文。
九月,李景隆至德州,收集耿炳文溃散士卒,并调各路军马共五十万,进抵河间驻扎。为了引诱李景隆深入,朱棣就叫姚广孝协助世子朱高炽防守北平,自己则率军援永平,这时攻围永平的江阴侯吴高退保山海关。朱棣率军直向大宁。大宁为宁王封地,所属朵颜诸卫,多为蒙古骑兵,骁勇善战。
朱棣起兵后,就想吞并它,扩张自己的军事力量。朱允炆也怕宁王与朱棣合兵,所以下令削除宁府的三护卫。朱棣得知这一情况后,认为这是袭取大宁的好机会,遂由刘家口直趋大宁。十月,合并了大宁宁王的部属及朵颜三卫的军队,才回师救北平。
李景隆听到朱棣去大宁,就帅师进渡卢沟桥,直抵北平城下。景隆几次攻城,皆被击退,遂顿兵于坚城之下,结九营于郑坝村。十一月,朱棣回师至北平郊外,进逼李景隆军营,城内燕军亦出击,内外夹攻,景隆不能支持,乘夜逃跑。第二天,士兵听说主帅李景隆已跑,“乃弃兵粮,晨夜南奔”。李景隆一直败逃到德州。
李景隆军败的消息传到南京,朱允炆问黄子澄:“外间近传军不利,果何如?”黄子澄隐瞒战败实情,谎称:“闻交战数胜,但天寒,士卒不堪,今暂回德州,待来春更进。”黄子澄并派人告诉李景隆:“隐其败,勿奏。”朱允炆在这些臣僚的蒙蔽下信以为真,加李景隆太子太师,予以奖励。
建文二年(1400年)四月,李景隆会武定侯郭英及安陆侯吴杰等“合军六十万,号百万”,进抵白沟河,以都督平安率精兵万骑为前锋。燕军方面,朱棣“使张玉将中军,朱能将左军,陈亨将右军,为先锋,丘福将步骑继之,马步十余万”。双方会战于白沟河,战争十分激烈,前锋平安和都督瞿能父子率军数败燕兵,燕军右军主将陈亨被平安所斩,朱棣的坐骑“凡三被创,三易之”。
南军虽多于燕军数倍,但由于“将帅不专,政令不一”,当取得胜利时,不能乘胜扩大战果,在遇到挫败时,不能部署兵力阻遏燕军的攻势。所以在瞿能父子战死、平安所部被燕军朱能所败后,“列阵大崩,奔走之声如雷,(俞)通渊与(滕)聚等皆死”。燕兵乘风纵火,烧其营垒,“郭英等溃而西,李景隆溃而南,委弃器械辎重山积,斩首及溺死者十余万”,“横尸百余里,景隆单骑走德州”,燕军跟踪追至德州。
五月,李景隆又自德州逃到济南。燕军追到济南,又败李景隆所率残部十余万人,围攻济南城。赖都督盛庸与参政铁铉死守,燕军围城三月未下,才撤军回北平。这时,朱允炆才感到李景隆的无能,便以盛庸代李景隆为大将军,擢升铁铉为兵部尚书,赞理大将军军事。