Echo — NASA Mars Climate Orbiter (1999)
What happened
NASA's Mars Climate Orbiter launched on December 11, 1998, and spent about nine months cruising to Mars. On September 23, 1999, it fired its main engine to slip into orbit, passed behind the planet as planned — and was never heard from again. Instead of settling into its intended orbit roughly 140 to 150 kilometers above the surface, the spacecraft came in far too low, at an estimated 57 kilometers, deep enough into the Martian atmosphere that it was destroyed. A machine that had flown flawlessly across hundreds of millions of kilometers was lost in its final minutes.
The mechanism
The failure was a units mismatch across an organizational seam. Navigation depended on two pieces of software owned by two different teams. Ground software built by Lockheed Martin produced a key thruster value — the small impulse from routine maneuvers — in English units, pound-force seconds. The navigation software at NASA's Jet Propulsion Laboratory consumed that same number as if it were metric, newton-seconds. The two units differ by a factor of about 4.45, so every value was quietly off by that factor.
Nothing crashed, because every number involved was a perfectly valid number. There was no malformed field, no exception, no failed checksum — just a legal quantity carrying the wrong meaning. The trajectory error accumulated silently over months of cruise. Navigators did notice discrepancies and raised concerns during the flight, but the issue was never fully run to ground before the orbit-insertion burn committed the spacecraft to a fatal approach.
Blast radius
The orbiter — a spacecraft that cost on the order of one hundred twenty-five million dollars to build and fly — was lost completely, along with the science mission it was sent to perform. Years of engineering and a nine-month interplanetary voyage ended over a mismatch of units at a software interface. The subsequent investigation made the incident one of the most-cited engineering failures in modern spaceflight, precisely because the root cause was so small and so preventable.
The same-class lesson
A number with no declared units is not data — it is a bet that both sides of an interface guessed the same convention. The units were the contract, and that contract lived only as an assumption in two separate codebases rather than as something written into the interface and checked at the boundary. That is exactly train-serve skew wearing a spacesuit: one quantity, two implementations owned by two teams, kept in agreement by hand until they silently drift. And it is a data-contract failure: no validation gate at the seam ever asked whether a value that was type-valid was also meaning-valid, so a number 4.45 times wrong sailed straight through. The transferable reflex is the same one the drills teach — compute or define a shared quantity once, make its contract explicit at the interface, and put a sanity check at the boundary that fires when the value drifts, because the failure is silent and no error rate will ever surface it.
Rhymes with
- Drill 87 — Train-Serve Skew: one computation, two implementations in two codebases, drifting because parity was maintained by hand instead of by a shared definition.
- Drill 7 — The Column Shift: a type-valid value carrying the wrong meaning across a system boundary, with no ingestion gate to catch it.
Named concepts: interface contracts, unit consistency, cross-team parity, boundary validation.
