An IFC file can pass every schema check available and still be wrong. Those are separate claims. Schema validation confirms a file is legally structured IFC, that every entity, attribute, and relationship conforms to the rules buildingSMART publishes for that version. It says nothing about whether the values inside it are the right values. A file can be perfectly legal and still hand a costing tool a number that describes the wrong thing, a corrupted quantity, or a piece of information the schema was never obligated to include in the first place.
This lesson works through four real, documented ways that gap opens up. Each comes from an actual IFC file, cross-checked by hand against the raw data. Each one also passes schema validation cleanly. That's the pattern worth holding onto: none of what follows is a broken file. All of it is legal IFC.
A real residential reinforced-concrete frame, exported from Revit 2021 as IFC2X3, contains 18 strip footings modelled as IfcFooting with PredefinedType STRIP_FOOTING. Every one of them carries zero Base Quantities. Not degraded values, not a partial set. Nothing. In the same file, every column, beam, and slab carries a complete quantity set.
This isn't inconsistent modelling. It's a documented limitation of that Revit export path: an "Export base quantities" checkbox exists in Revit's own IFC export dialog, and specific categories have historically not received quantities regardless of whether that box is checked. Foundation-level elements are one of them.
The real footing volumes, recovered independently from each element's IfcExtrudedAreaSolid geometry, range from 0.048 m³ to 2.384 m³ per element, a difference driven entirely by real footing lengths that range from a 0.049 metre connector piece up to an 18.275 metre perimeter run. A single default dimension applied uniformly across all 18, the only option available without reading geometry directly, is wrong on every element in the set, understating some by an order of magnitude and overstating others.
Nothing about the missing quantity set is a schema violation. IfcElementQuantity is optional on any element. A schema validator has no rule to break here, because there isn't one. It simply never receives the information needed to tell you a number is missing at all, let alone what the number should be.
A separate Revit IFC4 structural file contains an IfcStairFlight with these two Base Quantities:
GrossVolume: 0.00604 m³
NetVolume: 0.13724 m³
GrossVolume is more than twenty-two times smaller than NetVolume, on the same element. buildingSMART's own definitions of the two properties explain why that's backwards: GrossVolume is defined as the object's volume with openings, recesses, and similar features not taken into account, while NetVolume explicitly does take those features into account. By definition, removing material from a shape cannot make it bigger. NetVolume should never exceed GrossVolume.
The schema itself doesn't enforce that relationship anywhere. IfcQuantityVolume's only two formal constraints are that its value must carry a volume-type unit and that the value can't be negative. Nothing compares one instance of it against another with the same name on the same element. That means a validator checking this file sees two syntactically valid IfcQuantityVolume entries and has no rule to break, even though the two definitions directly contradict what's written here. Code that reached for GrossVolume by default, the more commonly reached-for of the two names, would report a stair flight at 0.006 m³ that is actually 0.137 m³, erasing the element from a concrete take-off almost entirely.
A real Allplan 2017 export of an underground car park contains 31 IfcWallStandardCase elements, all with complete, valid WallQuantities. Read at face value, they total 94.074 m³ of concrete. The real figure is 62.703 m³. Only 8 of the 31 walls are structural concrete. The other 23 are masonry, plasterboard, wood wool board, waterproofing, and natural stone facade layers, sharing the same element class and the same fully populated quantity set as the concrete walls around them.
The signal that actually distinguishes them is a field Allplan calls Gewerk, German for "trade": Betonarbeiten (concrete works) versus Mauerarbeiten (masonry works), Trockenbauarbeiten (dry construction), and several others. That field doesn't live in a standard property set. It sits inside IfcComplexProperty nodes, one per material layer, buried in an Allplan-specific structure called Object Layer Attributes.
This is where a large share of extraction code fails silently rather than loudly. IfcComplexProperty is a real, schema-legal entity, but per buildingSMART's own definition it holds a HasProperties set of nested IfcProperty entries, not a NominalValue. Code written to read a property's value by checking NominalValue, which is how the far more common IfcPropertySingleValue works, doesn't error out on an IfcComplexProperty node. It just finds nothing there and moves on, silently, with no exception raised. The classification information was never missing from the file. It was sitting one level deeper than the code was built to look.
Some of the 31 walls compound this further: they're multi-layer assemblies where the reported NetVolume covers every layer combined, not just the structural one. One wall reports a combined volume of 7.7574 m³ across a 420mm total build-up, of which only 300mm is the concrete layer. Recovering the real concrete volume means fraction-splitting: 7.7574 × (300 / 420) = 5.541 m³. Get the classification right and skip the fraction split, or get the split right without the classification, and the number is still wrong.
Schema validation has no opinion on any of this. Every wall's quantity set is complete and correctly formed. The failure lives entirely in a vendor's choice of where to put information the schema permits but doesn't require in any particular location.
A real Revit IFC4 production file includes a composite floor slab, modelled with a material of type IfcMaterialConstituentSet, carrying two constituents: Insulation and Concrete. The element's NetVolume reports 828.2727 m³, the combined volume of both materials together. Each constituent has a Fraction attribute meant to express what share of that total belongs to it. On this element, both are absent.
This is not a data entry oversight recoverable by looking harder. Per buildingSMART's own schema, Fraction on IfcMaterialConstituent is declared OPTIONAL, and MaterialConstituents itself is an optional set on IfcMaterialConstituentSet. A file can legally carry a constituent set with no fraction values at all, and this one does. There is no split to extract, because the split was never written, and the schema never obligated anyone to write it.
Pricing 828.2727 m³ directly as concrete overstates the real quantity by whatever the insulation layer actually accounts for. Excluding the element entirely underclaims a real structural floor. Neither choice is a bug fix, because there is no correct number sitting anywhere in this file waiting to be found. The only way to close this gap is for whoever authored the model to go back and add the fraction, which is a modelling decision, not an extraction one.
Four mechanisms, four different fixes. A missing category needs a completeness check, and even a passed completeness check only tells you data exists, not that the value is right. A corrupted-but-present value needs a plausibility check between related quantities, which a presence check would never catch. A vendor-specific hidden signal needs code that knows to look inside a specific proprietary structure, which no generic schema rule can anticipate. And a value the schema was never required to include needs a project-specific requirement, written down in advance, checked against the file after the fact. That last one is a different kind of check entirely from anything schema validation can offer, and it's where the next lesson in this series picks up.
Comments use a free GitHub account — takes under a minute to create, and keeps discussions spam-free and permanently archived.