The short answer
Program Faults
A program fault is the controller refusing to execute an instruction it cannot execute safely: an index outside an array, a pointer to memory that does not exist, a divide by zero on a platform that treats it as fatal, a call to a routine that is not there, or a task that could not finish before it was due to run again. The controller records the fault type, the code, the routine, and the rung or line, and either stops with a major fault or logs a minor one and continues, depending on the fault and the platform. The record is the diagnosis; the fault handler is the place to log it and decide whether to keep running; and the prevention is defensive logic that bounds every index, checks every divisor, and validates every value that comes from a screen or a network before using it.
Key points
- The fault record names the type, the routine, and the rung; read it before clearing anything.
- Major faults stop the controller and its outputs; minor faults are logged and execution continues.
- A fault handler routine can clear recoverable faults and log them, but a handler that clears everything hides a program that is broken.
- Bounds checks on indexes, checks on divisors, and limits on values from screens and networks prevent most program faults.
- Task overlap is a program fault too: the task took longer than its period.
The common ones
| Fault | What happened | Typical cause | Prevention |
|---|---|---|---|
| Array index out of range | An index addressed beyond the array bounds | An index from a screen, a counter that ran past, an off-by-one loop | Clamp or check the index before use |
| Invalid indirect address | A pointer or an indexed address pointed outside memory | Uninitialized pointer, a computed address that overflowed | Validate computed addresses; avoid pointers where indexes will do |
| Division by zero, overflow | Math produced a value the type cannot hold, or divided by zero | A flow total divided by a runtime of zero; an integer that overflowed | Check the divisor; use floating point for large values |
| Missing routine or block | A call to a routine that does not exist | A routine deleted or renamed; a partial download | Verify the project before downloading |
| Type mismatch | An instruction received a type it cannot use | A tag data type changed after the logic was written | Verify after any tag change |
| Task overlap | A periodic task was triggered before its previous execution finished | Too much logic in the task, a loop, or communications load | Measure the task time; move logic; fix loops |
| Watchdog | A task exceeded its watchdog time | As task overlap, or an infinite loop | See the watchdog article |
| Stack or nesting | Subroutine calls nested too deep, often recursive | A routine that calls itself through another | Restructure the calls |
Reading the record
- 1
The fault type and code
Major or minor, with a code that the controller manual maps to a description.
- 2
The location
The program, routine, and rung or line where the instruction faulted.
- 3
The values
The index, the address, or the operands at the time; the fault record or the tags at fault time show them.
- 4
The history
Whether this fault has happened before, from the fault log or the controller event log; a fault that recurs on a schedule has a cause on that schedule.
- 5
The trigger
What changed: a download, an online edit, a screen entry, a network write, a new device.
Fault handlers
Most platforms provide a fault routine that runs when a major fault occurs, and if it clears the fault the controller continues. That is useful for a fault the program can genuinely recover from, such as a bad index from a screen entry, where the handler logs the fault, resets the offending value, and lets the scan continue rather than dropping every output in the plant. It is dangerous as a blanket: a handler that clears every fault turns a broken program into one that silently skips instructions, and the first sign is a process doing something nobody programmed. The handler should log every fault with its code and location to a tag, clear only the fault codes it was written for, and count; a fault that clears more than a few times an hour is escalated to a controlled stop and an alarm.
Writing logic that does not fault
- Every index that comes from a calculation, a screen, or a network is clamped to the array bounds before it is used.
- Every divisor is checked for zero, and the result of a zero check is a documented default, not a skipped calculation.
- Values written from screens and networks land in staging tags, are validated against limits, and are then copied to the working tags.
- Integer math that can overflow is done in floating point or checked for range; totals use 32-bit or floating point accumulators with documented rollover.
- Loops have a bounded iteration count and no path that fails to advance the index.
- Task periods are set from measured execution times with margin, and the measured time is trended.
- The project is verified, and a full download is preferred to an online edit for structural changes.
After a fault at a running plant
A major fault drops the outputs, which means the pumps stopped or the valves went to their fail position, and the first job is the process: confirm what state it is in and whether local control or manual operation is holding it. Then the fault record is read and saved before anything is cleared, the cause is found in the logic, and the fix is tested offline where the platform allows. The controller is restarted with the operators aware of what the outputs will do on the first scan, which is the moment a poorly designed program restarts every pump at once.
Frequently asked questions
- The controller faulted once a week for months and cleared itself. Is that a problem?
- Yes. A fault handler is clearing a recurring program fault, and every occurrence skipped some logic. Read the fault log for the code and location and fix the cause; then make the handler count and alarm.
- How do I find which screen entry caused an index fault?
- The fault record gives the routine and rung, which names the array and the index tag; the index tag value at fault time, and the audit trail on the screen, name the entry. Then clamp the index and limit the screen field.
- Can a communications write cause a program fault?
- Yes, when the written value is used as an index, a divisor, or a pointer without validation. Every value that enters the controller from a network is treated as untrusted and validated before use, for safety and for security.
- Should I raise the task period or fix the logic when tasks overlap?
- Fix the logic if the overlap is new or the task time has grown; raise the period if the task genuinely needs the time and the process can tolerate the slower rate. Either way, measure first and document the decision.
Related topics
- Watchdog FaultsA task that did not finish in time: what the watchdog protects, why the scan grew, and how to fix it. Measuring task times, finding the loop or instruction that took the time, communications load, and when raising the watchdog is legitimate.
- PLC Will Not RunA controller that stays in program mode, faults on every attempt to run, or will not power up: the mode switch, the major fault log, the power supply, the memory and battery, the firmware and program mismatch, and the I/O configuration errors that stop a processor, in the order that finds them.
- Processor FaultedA PLC with its fault light on and no logic running. How to read what it is telling you, the causes in order of likelihood, and how to restart it without repeating the fault.
- Tasks and Execution PriorityHow a controller schedules its work: the continuous task, periodic tasks at a fixed rate, event tasks triggered by something happening, how priority preempts, and where each kind of logic belongs.
- Program OrganizationStructuring a controller program so that someone else can maintain it: a layout that follows the plant, one routine per job, standard device blocks, I/O mapped in one place, a fixed execution order, naming that means something, and comments that say why.
- Controller Mode Switch and KeyswitchThe physical switch on the front of a controller: what RUN, REMOTE, and PROGRAM mean, why most controllers are left in REMOTE and why that matters, a policy for a utility, how mode is monitored and alarmed, and what to do on platforms with no keyswitch.
Direct contact
Have a controls question?
Reach Eric Sullivan directly about anything on this site, a controls or automation topic, or one of his personal projects.