testing / safety-critical

Therac-25: When Testing Is a Matter of Life and Death

A case study of the Therac-25 radiation therapy disasters – six accidents, multiple deaths, and the testing lessons that changed medical software forever.

The patient felt a flash of heat. Not a burn from the outside – something deeper, like the radiation had passed entirely through her. She told the technician something was wrong.

The technician said that was impossible. The machine was state-of-the-art, computer-controlled, designed with multiple safety checks. It could not deliver more than the prescribed dose. That was the whole point of computer control.

She went home with that reassurance. By the time the truth surfaced, she had been massively overdosed – orders of magnitude beyond the intended dose. The machine that could not possibly overdose, had. Not once. Six times. Over two years.


The Machine

The Therac-25 was developed by Atomic Energy of Canada Limited (AECL) in partnership with CGR of France. Eleven units were sold across North America beginning in 1982. It was the most computerized radiation therapy machine of its time, using a DEC PDP-11 minicomputer to control the turntable that positioned the tungsten target, manage the beam current, and run the operator interface. In every sense, the software was the brain of the machine.

Previous models – the Therac-6 and Therac-20 – had used computers too. But those machines had extensive hardware safety interlocks: physical switches, redundant position sensors, mechanical locks. If the software made a mistake, the hardware caught it before the beam could fire. Both models could even operate without the computer at all, in a manual backup mode.

The Therac-25 removed those interlocks. The rationale was straightforward: software is more reliable than hardware. It does not wear out. It does not drift. It does not need calibration. Let the software do the checking.

This reasoning ignored one thing. When software is the only line of defense, a single failure becomes a catastrophe.


The Code

The software was not new. It was reused from the Therac-20 codebase – a practice AECL called “base duplication.” The thinking was simple: code that worked in one machine would work in another. The programming was done by a single developer, working alone, in PDP-11 assembly language. No independent review. No formal specification. The hazard analysis considered only hardware failures; software was assumed to be correct because it had run without incident on earlier models.

That developer left the company in 1986. When lawyers later tried to identify who had written the software, they were unable to determine the person’s name.

The software had been patched repeatedly. Each fix addressed a specific symptom. None addressed the underlying architecture. Testing was informal. Patches were released to hospitals without systematic regression testing. The U.S. Food and Drug Administration later found that AECL had no formal mechanism for hospitals to report incidents to a regulatory body – reports went to AECL, and AECL decided what to do with them.


The Accidents

The first known overdose occurred in June 1985 at the Kennestone Regional Oncology Center in Marietta, Georgia. The patient – a sixty-one-year-old woman named Katie Yarbrough, receiving follow-up treatment after a lumpectomy – felt a burning sensation when the beam activated. She told the technician she had been burned. The technician assured her that was impossible. She returned home, where she would later lose her breast, lose the use of her arm and shoulder, and live in constant pain. The machine was not examined. AECL was not informed.

In July 1985, at the Ontario Cancer Foundation in Hamilton, a forty-year-old woman receiving her twenty-fourth treatment for cervical cancer felt a burning sensation. The machine displayed an error code. The operator pressed the proceed key. The machine stopped again. The operator pressed proceed again. This happened five times. The patient later died from the overdose.

AECL investigated. They suspected a microswitch problem. They could not reproduce the failure. They changed the software to add an extra check and declared that the modifications represented a five-order-of-magnitude increase in safety. The machines remained in service.

In December 1985, a woman in Yakima, Washington, developed skin burns in a parallel band pattern after treatment. It took hospital staff months to connect the symptoms to the machine. By then, more patients had been treated and more damage had been done.

On March 21, 1986, at the East Texas Cancer Center in Tyler, a sixty-year-old man was receiving treatment for a tumor on his back. The machine displayed MALFUNCTION 54 – a code not explained anywhere in the user manual. The operator, a qualified radiation therapist, pressed proceed as she had been trained. The machine beeped again. She pressed proceed a second time. The patient felt a searing pain and later described the sensation as “an intense electric shock” (Leveson, 1993). He was hospitalized for radiation sickness and later died from the overdose.

One month after the March incident, on April 11, 1986, a second patient at the same center – a sixty-six-year-old man receiving treatment for skin cancer on his face – was overdosed on the same machine. The operator reported that the machine displayed MALFUNCTION 54 as well. This patient died from the overdose approximately three weeks later.

The physicist at Tyler, Fritz Hager, conducted his own investigation using film plates placed in the beam path. He proved that under a specific sequence of keystrokes, the Therac-25 would fire the full X-ray beam current without the target in place. AECL dismissed his findings. They said the failure was impossible. They sent a technician who could not reproduce the error and declared the machine functional.


The Root Cause

The Therac-25’s software had a race condition. It was subtle, intermittent, and devastating.

The PDP-11’s real-time operating system ran multiple tasks concurrently. One task handled the operator interface – accepting keystrokes, updating the display. Another task controlled the machine hardware: positioning the turntable, setting the beam energy, monitoring sensors. Both tasks shared access to certain variables in memory.

The critical variable was a flag that determined how the beam setup was configured. It was implemented as a counter rather than a fixed value – incremented each time a setup step ran. If the operator typed quickly enough, within an approximately eight-second initialization window, the user interface task could interfere with the machine control task. The turntable would not be in the correct position. The target would not be in the beam path. The software’s position check, subject to the same race condition, could be bypassed. The beam fired at full X-ray current with nothing in its path.

The counter had a second flaw. When incremented 256 times, it overflowed back to zero. The safety check thought everything was normal because the value wrapped around to the expected range.

The error appeared random because it depended on precise timing: a specific keystroke sequence entered within a narrow window after a particular setup sequence. Technicians would attempt to replicate it, fail, and report that the machine was working correctly.

When AECL later disassembled the code, they found that the same race condition existed in the Therac-20 software. It had never manifested because the Therac-20’s hardware interlocks caught it before the beam could fire. The bug was present for years – invisible because the hardware masked it.


The Institutional Failure

The technical bug is only part of the story. The institutional failures are the part that matters for testing.

AECL treated the software as an afterthought. The code had no independent review, no formal specification, no version control, and no systematic testing regime. The company’s hazard analysis considered only hardware failures. When hospitals reported overdoses, AECL dismissed them. The engineers believed the machine could not deliver a high dose without the target in place because the software prevented it. When presented with evidence that it had happened, they blamed the operators. This was not malice. It was a failure of organizational imagination.

The error messages made things worse. The machine displayed MALFUNCTION followed by a number from 1 to 64. The user manual did not explain these codes. Some indicated minor hardware issues. Others indicated catastrophic failures. The machine treated them the same way. Operators learned to press proceed whenever a malfunction appeared, because most of the time the machine recovered. They had no way to distinguish a recoverable error from a lethal one.

AECL never tested the Therac-25 as a complete integrated system before installation. The software was tested in isolation. The hardware was tested in isolation. The integration testing happened at the hospital, on the patients.

Helen Nissenbaum, analyzing the case in 1994, identified four barriers that prevented accountability: the problem of many hands (no single person responsible), software bugs used as a cover for poor development practices, the computer used as a scapegoat, and proprietary ownership without corresponding liability.


The Aftermath

By the time the Therac-25 was finally recalled in 1987, six patients had been massively overdosed. Leveson and Turner (1993) documented three fatalities among them. The survivors lived with permanent injuries. Lawsuits were settled out of court. AECL dissolved its medical division in 1988.

The case reshaped medical device regulation. The FDA restructured its reporting requirements for software-controlled medical devices, establishing mandatory incident reporting and pre-market review processes. International standards followed: IEC 62304 introduced development lifecycle requirements specific to medical device software, and ISO 14971 established formal risk management processes requiring manufacturers to identify hazards, estimate probabilities, and verify controls – including software controls – before a device reaches patients. These standards exist because the Therac-25 existed.

Nancy Leveson, who conducted the definitive investigation, summarized the lesson this way: “A naive assumption is often made that reusing software or using commercial off-the-shelf software will increase safety because the software will have been exercised extensively. Reusing software modules does not guarantee safety in the new system to which they are transferred.”

The Therac-25 is taught in every software engineering curriculum. It is cited in every medical device standard. It is the canonical case study of what happens when testing is treated as a formality rather than a discipline.


The Testing Lessons

First: software is not safer than hardware by default. Moving safety functions from hardware to software does not eliminate the risk. It transfers the risk to a domain that is harder to test, harder to verify, and harder to reason about. Every software check needs independent verification. Every assumption needs a challenge.

Second: code reuse is not code safety. The same bug lived in two machines. In one, hardware interlocks made it harmless. In the other, the interlocks were gone, and the bug was lethal. Reusing software without re-analyzing the context in which it runs is not reuse. It is a bet.

Third: the test you did not write is the one that matters. The race condition was intermittent, timing-dependent, and invisible under normal testing. It was never simulated because nobody believed it was possible. The most dangerous assumption in testing is that you have covered all the scenarios.

A concurrency-aware test harness with randomized timing injection would have caught this. So would a keystroke-level fuzzer aimed at the operator interface – feeding rapid edit sequences into the VT100 terminal while the machine was initializing, to probe for exactly this class of timing bug. Neither technique required exotic hardware. Both were well within the state of software testing practice in 1985. They simply were not part of AECL’s testing culture, because the software was not treated as a safety-critical component worthy of systematic verification.

Thirty years later, the tool names have changed, but the diagnosis is the same. If your system has concurrent tasks sharing mutable state, and your test suite does not include randomized concurrency stress, you are running the same experiment as AECL – and hoping for a different result.

Fourth: error messages are safety interfaces. A machine that displays MALFUNCTION 54 with no explanation, no severity indicator, and no recommended action is not just poorly designed. It is actively dangerous. Operators will learn to ignore warnings they cannot interpret. When every error looks the same, every error gets treated the same way.


The Question

The Therac-25 was withdrawn from service decades ago. The standards that emerged from it are mandatory in medical device development. The case study is taught in engineering curricula worldwide.

But the question it raises has not aged. What scenario are you assuming is impossible in the system you are building right now? Not the one you have tested. Not the one you have documented. The one you dismissed because you could not imagine it happening.

The Therac-25’s race condition could not be reproduced on demand. It appeared random. It was invisible under every standard test. Until it killed someone.

The code you are working on right now may not control a radiation therapy machine. But every non-deterministic failure started as a scenario someone thought was impossible. What is yours?


Sources

This case study draws primarily from the following sources.

Marcin June 19, 2026

Learn the full story of the Therac-25 software failures and what they teach about safety-critical testing.

Next step

Map this in one workflow.

Use the diagnostic kit to turn this problem into a concrete workflow map.