Oxford's slim hopes of making the League Two play-offs were finally dashed by Port Vale.
Jon-Paul Pittman went close for the visitors early on, but Marc Richards seized on a mistake by Jake Wright to put Vale ahead.
The U's brought on two forwards soon after the break after hearing Crewe were losing, but Sean Rigg fired in as Oxford were caught short at the back.
Ben Williamson poked in Richards's cross from close range to wrap it up.
Crewe's 2-2 draw with Aldershot
meant even a win would not have been enough to extend Oxford's season.
Oxford United boss Chris Wilder told BBC Radio Oxford:
"We've not done enough in the last six weeks and today epitomised that.
"We were comfortable in the first half and one mistake and we go in behind at half time and then we are chasing the game.
"But the season was not decided here today it was decided because we have drawn too many games and conceded too many late goals.
"We should have been in the play offs but we are not. We have to go again but I am hurting because I want to be successful with this football club.
"We want to get there as quick as possible, we put ourselves in a fantastic position and to not get the results in the last seven games means we did not deserved to be there.
Port Vale 12 Tomlinson 02 Yates (McDonald - 54' ) 05 McCombe Booked 26 Davis Booked 04 Griffith Booked 07 Loft 17 Rigg (Lloyd - 79' ) 20 Shuker 08 Dodds 09 Richards 11 Pope (Williamson - 81' ) Substitutes 25 McDonald 18 Morsy 21 James 32 Lloyd 19 Williamson Oxford United 31 Damian Martinez 02 Batt Booked 05 Duberry 06 Wright 16 Whing (Rendell - 52' ) 17 Capaldi 14 Hall 20 Leven 26 Davis (Chapman - 49' ) 11 Pittman Booked 29 Craddock (Johnson - 49' ) Substitutes 34 Crocombe 07 Chapman 19 Johnson 23 Rendell 27 Montano