# Byzantine Fault

A failure mode where a component doesn't just stop working — it continues operating but produces incorrect or misleading output. Named after the Byzantine Generals Problem (Lamport, Shostak, Pease, 1982), a thought experiment about coordinating an army when some generals may be traitors.

## The generals problem

Several generals surround a city and need to agree whether to attack or retreat. They communicate by messenger. Some generals may be traitors who send contradictory orders — telling one neighbor "attack" and another "retreat" — trying to break coordination so part of the army attacks while the rest retreats.

The proven result: you need more than 3f+1 total generals to tolerate f traitors. With 3 generals and 1 traitor, the 2 loyal generals cannot reliably determine which messages to trust. With 4 generals and 1 traitor, they can use majority voting to overrule the bad actor.

## Crash faults vs Byzantine faults

A **crash fault** is simple: the process stops. It sends no more messages. Other processes can detect this (eventually) by the absence of communication. This is the easier failure model — algorithms like Paxos and Raft handle it.

A **Byzantine fault** is any behavior that deviates from the protocol — wrong values, contradictory messages to different peers, selective silence, or arbitrary behavior. It's strictly harder to handle because you can't trust any single message from a potentially faulty node.

The practical difference is detection. A crashed node is obviously broken. A Byzantine node looks functional, which is what makes it dangerous.

Crash and Byzantine are the two endpoints software people usually name, but the full space of fault models — permanent vs transient, the redundancy schemes that mask each, and the reliability metrics used to compare them — is laid out from the hardware side in Dubrova's [[fault-tolerant-design]].

## Real-world examples

- A disk that silently returns corrupted data instead of reporting an error
- A misconfigured server that reports success to clients but doesn't actually persist writes
- A compromised node in a peer-to-peer network that lies about which blocks it has
- An LLM agent that confidently produces code based on a misread prompt — it didn't crash, it just interpreted things differently than every other agent ([[log-distributed-llms]])

## Handling Byzantine faults

**PBFT** (Practical Byzantine Fault Tolerance) is the classic algorithm — every node broadcasts its decision to every other node, and nodes accept the majority view. Expensive: O(n^2) messages per decision.

**Convert to crash faults** — the cheaper alternative. Instead of running Byzantine-tolerant protocols, add external validators that check output correctness. An agent that produces code that fails tests is now a detected crash (retry it) rather than a silent divergence. This is the strategy recommended in [[log-distributed-llms]] for multi-agent LLM systems, and it's the same reason databases use checksums on disk reads.

[[human-in-the-loop]] review serves a similar function — a human checking agent output is a Byzantine fault detector, catching cases where the agent's work is plausible but wrong.
