The Off-by-One Error

An off-by-one error is a bug in which a count or boundary is wrong by exactly one. The loop runs one iteration too many or too few, the array is indexed one element past its end, or a range includes one too many or one too few values. It is among the most common mistakes in programming because boundaries are where intuition and exact arithmetic most often diverge.

The error is also called a fencepost error, after the riddle that exposes the same trap: a straight fence one hundred feet long with posts every ten feet needs eleven posts, not ten, because the posts bound the gaps. Counting the things rather than the gaps between them, or vice versa, is the everyday source of off-by-one mistakes. Whenever a programmer asks “should this be less-than or less-than-or-equal,” a fencepost question is hiding underneath.

These errors are dangerous out of proportion to how small they sound. Reading or writing one element past the end of a buffer is a classic off-by-one, and that single extra step is enough to corrupt adjacent memory, crash a program, or open a security hole. Much of the historical record of buffer overflows begins with a loop bound that was off by one.

In a 1981 note, EWD831, Edsger Dijkstra gave a principled argument for why a particular convention reduces these errors. He compared ways of writing a range of integers and observed that “starting with subscript 1, the subscript range 1 <= i < N+1; starting with 0, however, gives the nicer range 0 <= i < N.” His preferred convention, a half-open range that includes the lower bound and excludes the upper, has two properties that prevent off-by-one mistakes: the number of elements is simply the difference of the two bounds, and adjacent ranges meet without overlap or gap.

This is why most modern languages number arrays from zero and use half-open ranges in their slicing and iteration constructs. The choice is not arbitrary aesthetics. It systematically removes the plus-one and minus-one adjustments that, done by hand under time pressure, are exactly where fencepost errors creep in. A convention that makes the common case require no arithmetic is a convention that produces fewer bugs.

Off-by-one errors will never disappear entirely, because boundaries are intrinsic to counting. But careful language design, defensive bounds checking, and tests that deliberately probe the empty case, the single-element case, and the last element turn most of them up before they reach production.

Sources

Last verified June 8, 2026