Neil Doak's side were looking to make it five league wins on the bounce to climb to second in the table as they eye a spot in the Belfast final.
But it was the 10th-placed Dragons, who seven days earlier had been stunned by bottom club Zebre, who took the spoils thanks to tries by hooker Rhys Buckley, scrum-half Jonathan Evans and full-back Carl Meyer.
Ulster had to settle for the consolation of a losing bonus thanks to a late score by Ross Adair, adding to Craig Gilroy's brace.
Ulster were on the front foot from the off, dominating possession and territory, yet it was the hosts that struck first with a penalty by wing Tom Prydie after 13 minutes.
The visitors responded on the quarter when Ireland international full-back Craig Gilroy finished off down the left after wing Rory Scholes sped through a midfield gap.
South Africa scrum-half Ruan Pienaar uncharacteristically shanked his conversion and the Dragons swiftly went back in front through another Prydie three-pointer.
Ulster were looking more dangerous with ball in hand but were faced with a determined Dragons defence and it was 6-5 at half-time, although Prydie was wide to the right of the posts with two long-range efforts in the closing stages.
The visitors were once again out of the blocks sharply from the restart and Pienaar, after a second woeful attempt from the tee, made it 8-6 with his third effort.
However, the Dragons came roaring back with fly-half Dorian Jones banging over a long-range penalty as Buckley - with Ulster prop Callum Black in the sin bin - crossing over from a driving lineout.
Ulster needed a charge in the final quarter to take the spoils, yet it was the unfancied hosts that stretched their lead to 21-8 in the 62nd minute when Evans dashed over from a ruck for a try that Jones converted.
Back came the Irish province with a second score by Gilroy after a break from captain Darren Cave but the Dragons secured their upset when full-back Carl Meyer finished strongly down the left after breaks by wings Ashton Hewitt and Hallam Amos.
At 26-15 up the hosts were in command but Adair dashed over from a quick lineout after 79 minutes to give Ulster a chance - but it was too little, too late.