Everybody budgets materials and labor. The line items that quietly eat the margin are the ones that do not produce anything you can see when you walk the house.
Permit fees. Engineering or architectural drawings when you move a wall or touch structure. Utility connection or tap fees. Debris removal, and the second dumpster nobody planned on. Temporary utilities during the work. Municipal inspection fees. Reinspection fees when something fails the first time.
The expensive one is code compliance you triggered by accident. You open a wall for a straightforward kitchen update and now the inspector wants the electrical brought current, or the stack replaced, or egress added because you touched the bedroom. That is not a sloppy contractor. That is the code doing what the code does, and it lands as a five-figure surprise on a job you budgeted as cosmetic.
Chris is right that contingency gets underestimated too, but I keep the two separate on purpose. Soft costs are predictable enough to estimate line by line before you close. Contingency is for what you genuinely could not see. When people bury soft costs inside contingency, they spend the contingency before the first real surprise shows up, and then they have no cushion left for the thing it was actually meant to cover.
Estimate what you can see. Reserve for what you cannot.
That's a tough split between Holding Costs (specifically lender cost) and Contingency.
These two kind've go hand in hand, but expect that you're going to miss some items on your original scope of work, which will lead to purchasing more materials and will take longer to get done (more labor cost and extended timeline).
I like to create my "full" scope of work before a project and then add a 10% Contingency. I've hit that AND more on pretty much all of my projects. There's just things you can't see / know on your acquisitions phase.
Then for lender cost, it really helps to breakdown your DAILY cost on your financing. That really get's your butt into high gear. For simple math, let's say you've got a $250k loan you're paying 11% on for a FLIP. Once you realize that's $75/day in interest only, you start to move your projects A LOT quicker.
Time. Time = money. The best planned schedule is useless when you hit a unseen problem, and sitting on the market longer than expected will kill a flip. Not only more monthly holding costs, but getting pushed into a different RE selling market (I.E. fall vs summer) is what has killed me.
Contingency is the right textbook answer, so I'll give the one I learned the expensive way over 28 years of building and flipping: nobody underestimates a line item as badly as they underestimate the calendar attached to it.
New investors budget dollars. They almost never budget days. Every line item on a rehab budget has a duration hiding inside it, and the duration is where the money leaks. A $12,000 roof that takes 3 weeks instead of 1 because the roofer no-showed twice isn't a $12,000 roof. It's a $12,000 roof plus 2 extra weeks of loan interest, taxes, insurance, and utilities, plus everything downstream that couldn't start until the roof was dry.
So the most overlooked line item, in my experience, is holding costs, but not because people forget to include them. They include them. They just calculate them against a fantasy timeline. If your carry is $3,000 a month and your 4 month project runs 6, which is about average for a first flip, that's $6,000 that was never in the budget. Bigger than most permit surprises. Bigger than most labor overruns.
Second place: the sell side. Buyer concessions, the price cut after 45 days on market, agent commissions on the real sale price instead of the dream ARV. I've watched more profit disappear between "rehab complete" and "check in hand" than during construction.
My fix is simple. Whatever timeline you believe, add 50% to it, then recalculate your holding costs and your loan interest on that number. If the deal still works, buy it. If it only works on the fast timeline, you don't have a deal. You have a bet on nothing going wrong, and something always goes wrong.