袁紹兼四州之地,擁兵十萬,實力遠在曹操之上,曹軍“諸將以為不可敵”。荀彧、郭嘉詳細分析了雙方的短長,曹操也激勵眾將說:袁紹“誌大而智小,色厲而膽薄,忌克而少威,兵多並分畫不明,將驕而政令不一”,是能夠戰勝的。由此,曹操集團才增強了決戰的信心。
建安四年(199)八月,曹軍進至黎陽(今河南浚縣),九月,退守官渡(今河南中牟縣)。次年正月,袁紹發布討曹檄文,二月,大軍開進黎陽。同時,派大將顏良渡過黃河,圍白馬(今河南滑縣),攻曹東郡太守劉延,曹操聽從荀攸分兵聲東擊西之計,領兵自官渡北向延津(今河南延津),佯裝去抄袁紹後方。袁紹中計,分兵增援延津。曹操便掉頭輕騎兼程直奔白馬,顏良倉促應戰,被殺,白馬之圍遂解。袁紹聞訊派兵追趕。曹操將輜重沿路棄置,誘袁軍爭搶,趁亂出擊,大敗袁軍,斬大將文醜。然後,勝利回師官渡。
袁紹敗了兩陣,不聽謀士勸說,急於求戰,進軍至官渡,“依沙塠為屯,東西數十裏”。曹軍也分營對峙,交戰失利後,堅壁不戰。袁紹利用自己人力、物力的優勢,堆土山,居高用箭射擊曹軍。曹兵在營中往來都必須用盾牌護身。於是,曹操命工匠造“霹靂車”,發射石塊打擊袁軍。袁軍又暗中挖地道,企圖通入曹營。曹軍便在營內挖長溝,破壞袁軍地道。兩軍如此兵來將擋,攻戰一月多,不分高下。
曹操兵少糧缺,士卒疲憊,與袁軍對抗難以堅持。他打算撤兵,寫信去許昌問荀彧。荀彧說,不能後退,隻要堅持,勝利有望。於是,曹操堅守官渡,尋找戰機。
袁紹大軍屯官渡,戰線過長,糧食從後方運來,糧秣供給不足。曹操看到袁軍這一弱點,用荀攸計,趁袁紹運糧車快到官渡時,派徐晃截擊,將袁軍幾千車軍糧一火焚光。袁紹又重新從河北運糧一萬多車屯於官渡大營北麵的烏巢(今河南延津)。