QR Code Basics

QR Code Error Correction Levels Explained

A QR code can still scan correctly even when part of it is torn, smudged, poorly printed, or deliberately covered by a logo. That resilience comes from Reed-Solomon error correction — the same class of algorithm used in CDs, DVDs, and satellite communication — built directly into every QR code's data structure. Understanding how it works helps you pick the right correction level for how a code will actually be printed and used.

How error correction works

When a QR code is generated, the encoder doesn't just write your data into the grid — it also calculates additional redundant data using Reed-Solomon codes and adds it alongside the original. This redundant data lets a scanner reconstruct missing or corrupted sections mathematically, similar to how a hard drive's RAID array can rebuild data after a disk failure. The tradeoff is capacity: the more redundancy you add, the fewer modules are left for actual data, so the same content requires a larger grid (a higher version number) as you increase the correction level.

The four correction levels

The QR code standard defines four fixed levels, each tolerating a different percentage of the code being damaged or obscured before it becomes unreadable:

  • L (Low) — ~7% recovery. The minimum redundancy. Produces the smallest, least dense code for a given amount of data. Appropriate for codes that will stay in pristine condition — displayed on a screen, or printed and kept somewhere they won't get damaged.
  • M (Medium) — ~15% recovery. The default in most QR code generators when no level is specified. A reasonable general-purpose choice for typical printed material like flyers or packaging.
  • Q (Quartile) — ~25% recovery. Meaningfully more resilient, at the cost of a denser code. Suited to codes exposed to wear — outdoor signage, warehouse labels, anything handled repeatedly.
  • H (High) — ~30% recovery. The maximum built-in redundancy. Necessary any time you're placing a logo or image in the center of the code, since that area is effectively "damaged" from the scanner's perspective and needs enough surrounding redundancy to reconstruct it. Also the right choice for codes on curved, textured, or industrial surfaces where print quality is inconsistent.

Choosing a level in practice

The decision mostly comes down to two questions: how much physical wear will the code be exposed to, and are you overlaying a logo or design element on top of it?

If neither applies — a clean digital code shown on a website or a screen — L is fine and keeps the code as simple and small as possible. For most printed, real-world use (flyers, receipts, packaging), M or Q is the sensible middle ground. If a logo is going in the center, H is not optional — anything lower risks the code failing to scan entirely, since the logo blocks real data modules that the scanner then has to reconstruct from redundancy that may not be sufficient at lower levels.

One caveat worth knowing: higher correction levels increase the module count for the same data, which means a smaller module size at a fixed print size — and past a certain point, a physically tiny, dense module grid becomes harder for a camera to resolve than the error correction can compensate for. If a code needs to be both small in print and heavily damage-resistant, shortening the encoded data (for example, using a dynamic QR code with a short redirect URL instead of a long one) does more for reliability than error correction level alone.