The Robustness Principle, aka Postel’s Law: be conservative in what you send, be liberal in what you accept. Coined by Jon Postel in an early TCP spec — your code should produce output that strictly conforms to the spec, but tolerate input that deviates from it as long as the intent is still clear.

A more formal restatement: be contravariant in the input type, covariant in the output type — accept the broadest reasonable set of inputs, return the narrowest, most predictable set of outputs.

Where it shows up

  • Parsers and deserializers that ignore unknown fields rather than rejecting the whole payload
  • APIs that accept multiple equivalent representations of the same value (e.g. case-insensitive headers)
  • Network protocols designed to keep working even when peers send malformed or unexpected packets

The case against it

The principle has aged less well than I’d have guessed:

  • Tolerance entrenches bugs. If your parser silently accepts a malformed message, every other implementation now has to replicate that tolerance to stay interoperable — “bug for bug compatible.” Martin Thomson’s argument (2015–2018 IETF drafts) is that this makes systems less robust over time, not more.
  • It can be a security hole. Being liberal about what you accept means accepting more attack surface. Rochet & Pereira (2018) showed this exact leniency exploited in Tor’s onion routing to deanonymize clients.
  • It defers pain rather than removing it. Marshall Rose’s take: a sloppy implementation works fine until, years later, it meets a strict one and breaks in a way that’s hard to trace back to the original violation.

My read: still a reasonable default for systems you don’t control both ends of, but worth pairing with explicit validation/logging at the boundary so “liberal acceptance” doesn’t quietly become “no idea what’s actually flowing through this system.”

See also

Further reading