
July 22, 2026
QR Code Error Correction: Complete Technical Guide
By Said Ouarrak · Founder
Every QR code you generate comes with a hidden trade-off that most people never think about: how much redundant data it carries. That redundancy, controlled by four levels named L, M, Q, and H, decides both how large the code becomes and how much damage it can survive before it stops scanning. The numbers you find in most guides — "7%", "15%", "25%", "30%" — are quoted from the ISO specification, but they describe a mathematical ideal, not what a real phone camera will tolerate. In this guide we explain exactly how Reed-Solomon error correction works, show you the measured grid sizes for real payloads, share the damage tests we ran on this site's own generator, and give you a reliable way to pick the right level for your print project.
What error correction actually is
A QR code is a grid of black and white modules. The payload — your URL, text, or Wi-Fi settings — is encoded into part of that grid as data codewords. Error correction adds a second set of codewords, computed by a Reed-Solomon algorithm, so a scanner can mathematically rebuild the original message when some of the codewords are missing or wrong.
The important nuance, and the source of most confusion, is what the recovery percentages apply to. The spec's 7–30% figure is the fraction of codewords that can be erased before reconstruction fails — calculated for an ideal reader under ideal conditions. It is not "7–30% of the visible square." A QR code also carries structural features with no error-correction protection: three finder patterns, timing lines, the format information blocks, and a single alignment pattern on larger grids. Damage to those features stops the scanner from even locating the code, and no amount of redundancy helps. Our damage-test results measured that difference directly.
The four error-correction levels
| Level | Codeword recovery (spec) | Typical job |
|---|---|---|
| L (Low) | ~7% | On-screen codes, controlled print, smallest grid |
| M (Medium) | ~15% | General print: labels, flyers, tickets |
| Q (Quartile) | ~25% | Logos, moderate abuse, outdoor-but-clean |
| H (High) | ~30% | Heavy abuse, folds, moisture, maximum margin |
Higher levels always mean more modules for the same payload. Because those modules must be a minimum physical size to be read, more modules also means a larger printed code — the topic of our sizing guide — or, at the same print size, a code that needs to be scanned from closer up.
Measured sizes: payload length × correction level
Instead of quoting a theoretical grid table, we generated real codes with the same encoder this site ships (qrcode v1.5.4) and measured the module grids for four byte-mode payload lengths at each level:
| Payload length | L | M | Q | H |
|---|---|---|---|---|
| 10 characters | 21×21 | 21×21 | 21×21 | 25×25 |
| 50 characters | 29×29 | 33×33 | 37×37 | 41×41 |
| 100 characters | 37×37 | 41×41 | 49×49 | 57×57 |
| 200 characters | 53×53 | 57×57 | 65×65 | 77×77 |
Two patterns jump out. First, the level penalty compounds with payload size: at 50 characters, moving from L to H changes the grid from 29×29 (841 modules) to 41×41 (1681) — roughly double the surface for the same data. Second, the commonly repeated claim that "H only adds 30%" refers to recovery capacity, not size: at 100 characters, H is 57×57 against L's 37×37, more than twice the module area.
Measured real-world tolerance, not folklore
The popular sentence "you can remove 30% of a QR code and it still works" needs to die. We tested it by generating a real 29-character URL at all four levels and decoding the codes after applying controlled damage; the full methodology and 24-trial-per-cell protocol live in our damage test. The headline table from that experiment — a centered black square, the way most people place a logo:
| Logo (centered) | L | M | Q | H |
|---|---|---|---|---|
| 5% of code area | 0% | 100% | 100% | 100% |
| 10% of code area | 0% | 0% | 100% | 100% |
| 15% of code area | 0% | 0% | 0% | 100% |
| 20% of code area | 0% | 0% | 0% | 0% |
Three consequences worth internalising:
- Level L has almost no practical margin. Even a 5% centered mark killed it. L is for ephemeral digital codes, period.
- The levels don't move in 7–15–25–30% steps in practice. Our measurements show roughly one-third to one-half of the spec number for localised damage: M handled about 5–10%, Q about 10%, H about 15% of centered damage before failing.
- Placing the logo in the centre is the safest possible choice — our centered square was the only model where Q and H showed a clear gradient. Random scattered marks, or a smudge that touches a finder or the bottom-right alignment pattern, can kill even level H at far lower percentages. The complete tables, including the corner-smudge collapse at 8%, are in the damage-tolerance post.
Choosing your level, honestly
L — digital and temporary only
If the code appears on a screen, in an email signature, or on a slide, and it will never be printed, L is the right call: smallest grid, fastest to scan, densest print. The moment ink, wear or a logo enters the picture, L is disqualified.
M — the standard print default
For flyers, labels, tickets and menus in good conditions, M is the sensible default: modest redundancy with the smallest practical printed size. Our inner-scribble test still got the payload out about 17% of the time at 10% localised damage, which suits the "occasionally smudged but otherwise clean" reality of most print.
Q — when you add a logo or expect some abuse
Our centered-logo measurement put Q's practical limit at roughly 10% of the code area covered, which comfortably fits a modest badge or wordmark. Any design that overlays the centre should start at Q and move to H if the badge is substantial.
H — durability over density
H is the level that survived a 15% centred logo, and it is the one you want for outdoor signage, packaging that folds, or anything that will be scanned after a hard life. Accept the larger grid; the extra scan reliability is the point.
How to pick your level in 5 steps
Step 1 — Decide what the code must survive. Write down the worst realistic condition: a logo in the centre, a crease through the middle, moisture, sun, another code's corner overlapping yours. "I want it to scan" is not a specification; "it must scan after the box is stacked, crushed and dusted, with a sticker over 10% of the centre" is. This single sentence decides whether you leave here with M or H.
Step 2 — Set the physical size from the scanning distance. Use the 10:1 rule from our sizing guide: a code scanned from 50 cm needs to be about 5 cm wide at least. A higher level makes that minimum larger in real terms because the module count grows, so decide the smallest required scan distance before you commit to a level.
Step 3 — Generate the real payload at the real size. Generate on this site's free QR generator using the final URL or text — not a placeholder — with error correction set to your candidate level. Export at 300 DPI if it will be printed, or as SVG so the modules stay crisp at any size.
Step 4 — Run the damage tests your materials actually face. Truncate or re-test with the damage-tolerance numbers: cover the centre with a square of the same relative size as your logo and verify; smudge the bottom-right corner; if folding is real, generate and scan after a physical fold. One 24-trial run is worth more than any table you have read, including the tables in this guide.
Step 5 — Move up a level until it passes, then stop. If M fails your stated condition, regenerate at Q and retest the identical scenario, then H. Our measurements predict you will see a step change rather than a smooth curve, so the marginal level is easy to find. When the code passes its own worst case, that is the level to ship — not the one that produced the prettiest grid.
Troubleshooting
The code fails even though I chose H. Then the failure is almost certainly not correction capacity — check for damage to a finder pattern, the timing lines, or the bottom-right alignment pattern, none of which Reed-Solomon protects. Re-run the corner and random models from the damage test on your exact code.
My printed code is larger but still won't scan. Raising the level made the grid denser; if you kept the same printed size, each module got smaller and the camera may no longer resolve it. Re-check the size needed at the new module count with the sizing guide rather than assuming it will behave identically.
A QR reader says "invalid" although everything looks clean. Also verify that a valid quiet zone exists (four modules of clear space on all sides), and that the code isn't reversed, mirrored, or exported from a screenshot that compressed the edges.
The stop scanning after heavy UV / long logo coverage. This is exactly why we do not publish "months of life" numbers: real endurance depends on ink, substrate and climate. If exposure is a factor, choose H, and physically age-test a sample (UV exposure, scratching, water) before production, using the same scan protocol.
FAQ
What does 7%/15%/25%/30% actually mean? It is the spec's codeword erasure capacity. In our measurements of realistic damage, the practical margin was about one-third to one-half of those figures for centred, localised damage — and near zero for damage touching structural features.
Does higher error correction always mean a bigger code? Not always in module count for short payloads (10 characters measured identical 21×21 grids at L/M/Q), but almost universally by the time the payload grows: at 100 characters, H measured 57×57 against L's 37×37, more than double the surface.
What level do most generators default to? M gives the common default. For this site's generator you can choose any level; start at M and step up if your design adds a logo or abuse potential.
Can I change the level after generating? Only by regenerating — the level is baked into the grid. Regenerate with the same payload at the new level; the URL or text doesn't change, only the code's physical pattern.
Should I just always use H? H gives the most margin but the largest grid, which can force a larger print size or a shorter practical scan distance. Reserve H for real durability needs and use M for clean print, exactly as the decision table above suggests.
Put the right level on your code
Error correction is the difference between a code that lives and one that embarrasses you at the counter. M covers clean print, Q covers logos, H covers real-world abuse, and L is digital-only. Pair the level with a verified print size and a quick damage test on your actual artwork, and your code will scan long past the moment it gets dinged.
Generate a QR code with the level you chose — set L, M, Q, or H on the generator, export at print resolution, and test your design under its worst-case scenario.