Why QR Codes Need Error Correction
A QR code printed on a product label will be scratched, stained, and partially obscured over its lifetime. A code on a poster will face rain, sun bleaching, and the occasional sticker plastered over it. A code on a screen will be photographed at odd angles in dim lighting. If QR codes stored data without any redundancy, even minor damage would render them unreadable.
This is the problem that Reed-Solomon error correction solves. Named after Irving S. Reed and Gustave Solomon, who published the foundational algorithm in 1960, it adds carefully calculated redundant codewords to the data payload. These aren't random copies of the data — they're mathematically derived values that allow a decoder to both detect where errors have occurred and correct them without any human intervention.
The QR code specification (ISO/IEC 18004) mandates Reed-Solomon encoding for all QR codes. Every code you've ever scanned carries this protection. The only variable is how much redundancy is included, which is controlled by the error correction level setting during generation.
Reed-Solomon is a block code: it operates on fixed-size blocks of symbols rather than individual bits. In QR codes, each symbol is one byte (8 bits), and the code operates over a mathematical structure called GF(28) — a Galois field with 256 elements. This is why the arithmetic looks unfamiliar: it obeys different rules than ordinary integer math.
Galois Field Arithmetic: The Mathematical Foundation
To understand Reed-Solomon encoding, you need to understand the number system it uses. Ordinary arithmetic won't work because operations like multiplication and division can produce values outside the valid range (0–255 for a byte). Galois field arithmetic guarantees that every operation produces a result that is still a valid byte-sized value.
What Is GF(28)?
GF(28) is a finite field containing exactly 256 elements, numbered 0 through 255. Each element can be thought of as an 8-bit binary number, but the way you add, multiply, and divide them is different from standard integer arithmetic. Two rules define the field:
- Addition (and subtraction): Performed as bitwise XOR. In GF(28), addition and subtraction are the same operation. For example, 53 + 17 = 53 XOR 17 = 36. There is no concept of "carrying" a bit.
- Multiplication: Performed as polynomial multiplication modulo an irreducible polynomial. QR codes use the irreducible polynomial x8 + x4 + x3 + x2 + 1 (binary: 100011101, decimal: 285). This ensures the result always stays within 0–255.
Logarithm and Exponent Tables
Multiplication in GF(28) is computationally expensive if done naively. In practice, QR encoders use precomputed log and antilog (exponent) tables based on a primitive element, typically α = 2. Every non-zero element in the field can be expressed as a power of α. To multiply two elements, you look up their logarithms, add the logs (modulo 255), and look up the antilog of the result. This converts field multiplication into simple table lookups and integer addition.
// GF(2^8) multiplication using log/antilog tables
function gf_multiply(a, b) {
if (a === 0 || b === 0) return 0;
return EXP_TABLE[(LOG_TABLE[a] + LOG_TABLE[b]) % 255];
}
// GF(2^8) addition is simply XOR
function gf_add(a, b) {
return a ^ b;
}This property — that every non-zero element is a power of a single generator — is what makes Galois fields so useful for error-correcting codes. It gives the mathematics a consistent, predictable structure that algorithms can exploit to locate and repair errors.
Generator Polynomials: Building the Redundancy
Once you have Galois field arithmetic, the next step is constructing a generator polynomial. This polynomial determines how many error correction codewords are produced and what values they take.
The generator polynomial for t error correction codewords is the product of t linear factors:
g(x) = (x - α0)(x - α1)(x - α2) ... (x - αt-1)Remember that subtraction in GF(28) is the same as addition (XOR), so each factor is really (x + αi). The encoder multiplies these factors together using GF arithmetic to produce a polynomial of degree t with t + 1 coefficients.
To generate the error correction codewords, the encoder treats the data as a polynomial m(x), multiplies it by xt to make room for the EC codewords, then performs polynomial long division of xt · m(x) by g(x) using GF arithmetic. The remainder of that division is the set of error correction codewords, which are appended to the data codewords in the QR code.
The number of EC codewords varies by QR version and error correction level. A Version 1-H code produces 17 EC codewords from a generator polynomial of degree 17. A Version 40-H code produces hundreds. The QR specification includes lookup tables mapping every version/level combination to the exact EC codeword count. See the full specification breakdown in our QR code technical specifications guide.
Syndrome Calculation: Detecting and Locating Errors
When a scanner reads a QR code, it receives a sequence of codewords that may contain errors — corrupted, missing, or misread values. The decoder's first task is to determine whether errors exist and, if so, where they are and what the correct values should be.
Computing the Syndrome
The decoder evaluates the received polynomial r(x) at each root of the generator polynomial (α0, α1, ..., αt-1). If the received message is error-free, every evaluation will return zero. If any syndrome value is non-zero, errors are present.
// Syndrome calculation
Si = r(αi) for i = 0, 1, ..., t-1
// If all syndromes are zero: no errors
// If any syndrome is non-zero: errors detectedError Location and Correction
After detecting errors via non-zero syndromes, the decoder uses the Berlekamp-Massey algorithm (or equivalently, Euclid's algorithm) to find the error locator polynomial. The roots of this polynomial reveal the positions of the corrupted codewords. Then, the Forney algorithm computes the error magnitudes — the exact values needed to correct each corrupted codeword. The decoder XORs these correction values with the received codewords to recover the original data.
This three-step process — syndrome calculation, error location, error correction — happens entirely within GF(28) arithmetic and is deterministic. There is no guessing. If the number of errors is within the correction capacity, the algorithm will find and fix every single one.
For a deeper look at how data is structured before Reed-Solomon encoding is applied, see our guide on QR code encoding modes, which covers numeric, alphanumeric, byte, and kanji encoding.
The Four Error Correction Levels
The QR code specification defines exactly four error correction levels. Each one represents a different trade-off between damage tolerance and data capacity. Higher error correction means more redundant codewords, which means the code must be physically larger (or store less data) to accommodate them.
| Level | Recovery Capacity | Data Overhead | Typical Use Case | Robustness |
|---|---|---|---|---|
| L (Low) | ~7% of codewords recoverable | Lowest — maximum data capacity | Clean, controlled environments (screens, indoor signage) | Basic |
| M (Medium) | ~15% of codewords recoverable | Moderate — good balance | General purpose (business cards, packaging) | Good |
| Q (Quartile) | ~25% of codewords recoverable | Higher — reduced data capacity | Outdoor use, industrial labels, moderate wear | Strong |
| H (High) | ~30% of codewords recoverable | Highest — significantly reduced capacity | Logos embedded in centre, harsh physical environments | Maximum |
The capacity impact is significant. For example, a Version 10 QR code at Level L can store 652 numeric characters. The same Version 10 code at Level H stores only 346 — nearly half the capacity sacrificed for maximum error protection. If your data payload is fixed, moving from Level L to Level H may force the generator to use a larger QR version, producing a physically bigger code.
The "30% recovery" figure for Level H means 30% of data codewords can be corrupted and still be recovered. It does not mean 30% of the physical QR code surface can be destroyed. Damage to structural elements — finder patterns, timing patterns, or the quiet zone — can cause scan failure regardless of EC level. The structural elements are not protected by Reed-Solomon encoding.
Real-World Damage Scenarios
Understanding how Reed-Solomon protection performs under real damage conditions is essential for choosing the right EC level. Here are common scenarios and how the error correction system handles each one.
Scuffed or Scratched Surface
A QR code on a product label that's been dragged across a shelf typically suffers localised linear damage — a scratch across several rows of modules. If the scratch affects data modules only (not finder patterns), Reed-Solomon can usually recover the data at Level M or above. Scratches that cross a finder pattern may prevent the scanner from locating the code entirely.
Partial Obstruction (Stickers, Dirt, Fingers)
A thumb covering part of the code, a price sticker overlapping a corner, or accumulated grime all create localised patches of unreadable modules. Level Q (25%) handles moderate obstruction well. Level H is recommended for environments where partial covering is expected — warehouse labels that collect dust, or packaging that may receive secondary stickers.
Logo Embedded in Centre
When you embed a logo in the centre of a QR code, you are intentionally destroying data modules. The logo area becomes a block of unreadable codewords that Reed-Solomon must compensate for. Level H is mandatory for logo overlays. Keep the logo under 20% of the code area to maintain a safety margin within the 30% recovery budget.
Fading and Sun Bleaching
UV exposure gradually reduces contrast between dark and light modules. This doesn't destroy individual modules cleanly — instead, it creates ambiguity across the entire code. Reed-Solomon can correct scattered errors, but when contrast drops uniformly below the scanner's threshold, the entire code fails at once regardless of EC level. For outdoor codes, prioritise UV-resistant inks and materials alongside a higher EC level.
Water Damage and Ink Bleed
Water can cause ink to bleed, merging adjacent modules into unreadable blobs. This creates clustered errors that consume correction capacity quickly. Level H provides the best chance of survival, but severely water-damaged codes often fail because the damage destroys both data and structural elements simultaneously.
Generate Error-Corrected QR Codes
Choose your EC level, encode your data, and download a production-ready QR code — free, no account needed.
Choosing the Right Error Correction Level
The right EC level depends on two factors: how much physical damage the code is likely to face, and how much data you need to encode. Here's a decision framework:
- Level L (7%): Use when the code will be displayed on a screen or in a clean indoor environment, the data payload is large, and you need the smallest possible QR code size. Digital menus, app download links on monitors, and email signatures are good candidates.
- Level M (15%): The default for most generators and the right choice for general-purpose printed codes — business cards, brochures, product inserts, and indoor signage. Handles minor wear and typical scanning conditions well.
- Level Q (25%): Choose for outdoor signage, industrial labels, shipping cartons, and any context where moderate physical wear is expected over the code's lifetime. Also appropriate for codes printed on textured or uncoated surfaces where ink absorption may be uneven.
- Level H (30%): Required when embedding a logo in the code centre. Also recommended for harsh environments (factory floors, construction sites, agricultural products) and for codes that must remain scannable over months or years of physical exposure.
For a complete reference on QR code version sizes, module counts, and capacity tables across all four EC levels, see the QR code technical specifications pillar guide.
Reed-Solomon error correction is what makes QR codes practical in the physical world. Galois field arithmetic provides the mathematical foundation, generator polynomials create the redundant codewords, and syndrome calculation locates and fixes errors at scan time. Choose Level M for everyday use, Level H when embedding logos or expecting damage, and always remember that structural elements (finder patterns, quiet zone) are not protected by EC — keep them intact.
Frequently Asked Questions
Reed-Solomon error correction is a mathematical algorithm used in QR codes to add redundant data codewords. These extra codewords allow a scanner to detect and repair errors caused by physical damage, dirt, or poor printing. The algorithm operates over Galois field GF(28) and can recover data even when a significant portion of the QR code is unreadable.
It depends on the error correction level. Level L recovers from approximately 7% damage, Level M from 15%, Level Q from 25%, and Level H from up to 30%. These percentages refer to the proportion of codewords that can be missing or corrupted while still allowing full data recovery. Damage to non-data areas like the quiet zone or finder patterns can cause scan failure regardless of EC level.
Use Level H (30% recovery) when embedding a logo in the centre of your QR code. The logo physically obscures data modules, so you need maximum redundancy to compensate for the lost information. Even at Level H, keep the logo area under 20% of the total code to maintain a safe margin. Level Q (25%) can work for very small logos but offers less safety margin.
A Galois field (also called a finite field) is a mathematical structure with a fixed number of elements where addition, subtraction, multiplication, and division are all defined and always produce results within the field. QR codes use GF(28), which contains exactly 256 elements (0 to 255). This maps perfectly to byte-sized data. All Reed-Solomon arithmetic — generating error correction codewords, calculating syndromes, and locating errors — happens within this field.
No. Reed-Solomon error correction only protects the encoded data codewords and format information. The three finder patterns, alignment patterns, and timing patterns are structural elements that the scanner uses to locate and orient the QR code before decoding begins. If a finder pattern is severely damaged, the scanner may fail to detect the QR code entirely, regardless of the error correction level applied to the data.