QR Code Error Correction Explained: L, M, Q, and H Levels
Every QR code has a hidden error-correction level that determines how much damage it can survive. Here's how to pick the right one for your use case.
Every QR code carries more data than the bytes you're encoding. Roughly 7-30% of the matrix is redundant information, computed using Reed-Solomon error correction, that allows the QR reader to reconstruct the original data even if part of the code is damaged, obscured, or distorted.
You get to choose how much redundancy to add. The choice is one of four levels: L (Low, 7%), M (Medium, 15%), Q (Quartile, 25%), H (High, 30%). Each level trades data capacity for resilience — and the right choice depends entirely on how the QR code will be used.
How Reed-Solomon error correction works
Without going deep into the math, Reed-Solomon encoding adds redundant polynomials to your data so that errors can be detected and corrected. The number of error correction codewords determines how much damage the code can survive.
For a QR code version 5 (a common mid-size version), the capacities are:
- L: 154 data bytes, 36 error correction bytes (19% of total)
- M: 122 data bytes, 68 EC bytes (36%)
- Q: 87 data bytes, 104 EC bytes (54%)
- H: 67 data bytes, 124 EC bytes (65%)
Notice that the data capacity drops dramatically as you go from L to H. The total matrix size is fixed for a given QR version — you're trading data space for redundancy.
The percentages in the level names (7%, 15%, 25%, 30%) refer to how much of the QR code can be damaged or obscured while still being readable. So an H-level code can lose 30% of its visible modules and still decode perfectly.
When to use each level
Level L (Low, 7% recovery)
Use L when:
- The QR code will be displayed digitally (screen to screen)
- The surface is clean and intact
- Maximum data capacity is needed
- Aesthetic flexibility (gradient colors, custom dot shapes) matters more than scannability
L is fine for a QR code on a website that you scan with your phone — the screen is pristine, the lighting is good, and the code is unaltered. Most data-heavy use cases (vCard contacts, complex URLs) work fine at L.
Level M (Medium, 15% recovery)
Use M when:
- The QR code will be printed
- It might be slightly dirty or worn
- It will be scanned from a slight distance or angle
M is the default for most QR generators and the safe choice for general-purpose use. A printed menu on a table, a poster at eye level, a flyer handed out at a conference — all of these are M-territory. It survives normal wear and tear without sacrificing too much data capacity.
Level Q (Quartile, 25% recovery)
Use Q when:
- The QR code will be placed in a high-traffic area
- It might be partially obscured (a corner folded over, a sticker on top)
- You're adding a small logo to the center
Q is the minimum level recommended when you're overlaying a logo. A logo covers modules in the center of the code, and the error correction has to reconstruct that area. Below Q, the logo area is too large relative to the redundancy.
Level H (High, 30% recovery)
Use H when:
- The QR code will be placed outdoors
- It might be scratched, weathered, or partially torn
- You're adding a large logo or artistic overlay
- The code will be engraved or embroidered (where physical reproduction introduces errors)
H is the choice for industrial use — QR codes on shipping containers, equipment tags, machinery labels. It's also what you want for marketing materials where the QR code is decorated with brand elements that cover a significant portion of the matrix.
The logo problem
Adding a logo to a QR code looks great and improves brand recognition — but it removes data modules. The general rule:
- Logo should cover no more than 10-15% of the QR code area
- Use at least level Q error correction
- Test with multiple devices after adding the logo
A logo covering 20% of a level-L code will break it. A logo covering 20% of a level-H code will usually still scan. The error correction can reconstruct what the logo obscures — but only if there's enough redundancy to do so.
TextOpal's QR generator includes a scannability checklist that flags logo size relative to the chosen EC level. If you've added a logo that's too large for the current EC level, the checklist shows a warning with a one-click "Fix" that bumps the EC level up.
How error correction interacts with QR version
QR codes come in 40 versions, ranging from 21x21 modules (version 1) to 177x177 modules (version 40). The version is automatically determined by the amount of data being encoded — more data requires a larger matrix.
For a given version, the data capacity depends on the EC level:
- Version 5 at L: 154 bytes → enough for a typical URL with UTM parameters
- Version 5 at H: 67 bytes → enough for a short URL, but not much else
- Version 10 at H: 271 bytes → enough for a vCard contact card
The QR generator you use should automatically pick the smallest version that fits your data at the chosen EC level. If you're hitting the maximum version (40) and still running out of space, you need a shorter URL (use a URL shortener) or a different EC level.
The aesthetic tradeoff
Higher EC levels mean more modules dedicated to redundancy, which means the QR code looks denser and more complex. Lower EC levels produce cleaner, more minimalist codes that look better in marketing materials.
Designers often push for the lowest EC level because the result looks better. The tradeoff is real — but resilience matters more than aesthetics. A beautiful QR code that doesn't scan is a wasted print.
The middle path: use level M for most cases, Q when adding a logo, H for industrial or high-wear applications. Only drop to L when you're sure the code will be displayed in pristine conditions.
Custom dot shapes and gradients
Modern QR generators offer square, circle, diamond, pixel, drop, and line dot shapes, plus solid colors or three-direction gradients. Each of these affects scannability:
- Square dots are the safest choice — they're what QR scanners expect.
- Circle dots scan reliably with most modern phones but may fail on older scanners.
- Diamond and pixel shapes are decorative; expect reduced scannability.
- Gradients should be subtle — high contrast between adjacent modules is what scanners need.
Pair these with error correction: a custom dot shape on a level-L code will often break it. Bump to M or Q when using decorative shapes.
Testing in the real world
After generating a QR code, test it with:
- Multiple phones (different camera qualities, different scanning apps)
- Different lighting conditions (bright office, dim restaurant, outdoor shade)
- Different distances (close, arm's length, across the room)
- Different angles (head-on, 45 degrees, from the side)
The Android BarcodeDetector API (used by Chrome's QR scanner) is more permissive than iOS's native scanner. Test on both platforms.
If the code reliably scans across these conditions, ship it. If not, bump the EC level, simplify the design, or use a smaller data payload.
The bottom line
QR code error correction is a tradeoff between data capacity and resilience. For most use cases — printed menus, posters, business cards — level M is the right default. Add a logo? Bump to Q. Outdoor or industrial? Go to H. Pure digital, maximum data? L is fine.
The choice you make directly affects whether your QR code works in the real world. A 30-second decision at generation time can save hours of support tickets later. TextOpal's QR generator lets you switch EC levels instantly, see the resulting matrix, and run a real scan test before you download — all in your browser, with no data ever uploaded.