QR Code Free Forever QR Code Free Forever Create QR codes. 100% free. Forever. Make a QR code

Home · Guides

QR Code Error Correction Explained

Every QR code carries a spare copy of itself. The level you pick decides how much of the code can be destroyed before the spare runs out — and, as it turns out, where the damage lands matters more than how much of it there is.

What the four letters mean

A QR code does not just store your data. It stores your data plus a block of Reed–Solomon check symbols, computed from the data, that let a scanner rebuild bytes it could not read. The error-correction level decides how big that block is.

LevelRecovers aboutTypical use
L7% of codewordsScreens, clean printing, long payloads
M15% of codewordsThe sensible default for print
Q25% of codewordsCodes that will be handled, or carry a logo
H30% of codewordsPackaging, outdoors, fabric, anything abused

Two things about that table are worth pinning down, because almost every article about QR codes gets them slightly wrong.

First, the percentages are shares of codewords — the 8-bit blocks the symbol is divided into — not shares of the picture. A codeword is spoiled by a single wrong module, so losing 30% of the codewords does not require losing 30% of the area. It can require much less.

Second, the numbers are a nominal capacity, not a guarantee. What a real scanner manages depends on how the damage is distributed. That is what we set out to measure.

What the higher levels cost you

The check symbols have to live somewhere. Ask for more of them and, for the same message, the code needs a larger grid — a higher version, in QR terminology. Version 1 is 21×21 modules and every step adds four modules per side, up to version 40 at 177×177.

The same URL as four QR codes at error correction levels L, M, Q and H, growing from 29x29 to 41x41 modules
The same 53-character URL encoded at each level. Level L fits in a 29×29 grid; level H needs 41×41 for the same message. Printed at the same physical width, every module in the H code is 30% narrower — which is its own kind of fragility.

This is the trade nobody mentions. If the code has a fixed physical size — a 20 mm square on a business card, say — then choosing H does not make it tougher in any simple sense. It buys redundancy and pays for it with smaller modules, and small modules are harder for a camera to resolve. On a card read from 20 cm that is usually a bad bargain. On a shipping carton that will be scuffed, it is a good one.

The rule that falls out of this: raise the level when the code will be damaged, raise the size when the code will be far away. They are different problems.

What we measured

We built a small test bench for this site. A version 5 symbol (37×37 modules) carrying a 33-byte URL was generated at each of the four levels, so all four codes are exactly the same size and only the redundancy differs. We then damaged them in two ways and asked a decoder to read them back — 80 attempts per data point, roughly 12,000 decodes in total.

The first damage model is a blot: one white rectangle, dropped at a random position over the data area. A price sticker, a thumb, a scrape.

Grid of QR codes at levels L, M, Q and H with 5, 10, 15 and 20 percent of the symbol covered, marked as readable or not
One contiguous blot over the data region. A cell is green only if all 80 attempts decoded correctly. The percentages are shares of the whole symbol area.
4%largest blot level L survived every time
9%level M
14%level Q
17%level H

Those figures are lower than the 7 / 15 / 25 / 30 headline numbers, and they should be: a blot covering 17% of the whole symbol destroys a larger share of the data region, because roughly a fifth of the symbol is taken up by function patterns that carry no payload at all.

Scattered damage is the real killer

The second model spreads the same total area of damage over the whole code as individual flipped modules — the pattern you get from a streaky printer, ink spatter, dust, or a fabric weave.

Two line charts comparing decode success against damage, showing scattered damage failing at far lower percentages than a single blot
Decode rate against the share of the symbol damaged, for one contiguous blot (left) and for the same area scattered as individual modules (right). Both panels share an axis. 80 attempts per point; function patterns were left intact so that the curves isolate error correction.
LevelBlot survivedScatter survivedRatio
L4%1%4×
M9%2%4.5×
Q14%2%7×
H17%3%5.7×

Concentrated damage is between four and seven times more survivable than the same area scattered. The reason is structural. Reed–Solomon correction works on codewords, and a codeword is ruined by one bad module just as thoroughly as by eight. A blot destroys a handful of codewords completely and leaves the rest untouched. The same number of modules sprinkled across the symbol spoils a different codeword almost every time, so the error budget is spent many times faster.

The practical consequence: a code with one clean coffee stain on it will very likely still scan. A code printed with a nearly-empty toner cartridge, speckled all over, very likely will not — even though it looks less damaged.

This also explains a failure that puzzles people: a code that scanned perfectly from the screen, printed on a cheap inkjet onto absorbent paper, and stopped working. Nothing dramatic happened to it. Ink bleed nibbled a fraction of a module off thousands of edges at once, which is the scattered case, and the scattered case is where the error budget disappears.

The parts no level can repair

Error correction protects the data region. It does not protect the machinery that lets a scanner find and read the grid in the first place — and that machinery has, in our tests, essentially zero tolerance.

So the useful mental model is not "H codes survive 30% damage". It is: the middle of the code is forgiving and the edges are not. If you are going to punch a hole, trim a corner or overlap a code with anything, the safe place is the centre — which is exactly why centre logos work and corner crops do not. See the anatomy of a QR code for what each of those regions is doing.

Choosing a level

Three questions get you there.

If you are not sure: M. It is the default in most generators for a reason, and the measured gap between M and Q only starts to pay off once the code is genuinely at risk.

Everything on this site is generated at the level you choose, in your browser, and stays valid forever because the data is inside the image rather than on a server. If you want the reasoning behind that, see static versus dynamic QR codes.

Written by Manuel Llovet, who builds and maintains QR Code Free Forever. Published 2026-08-31, last checked 2026-09-08. Figures and measurements on this page were produced for this site; the method is described in each caption.

Make this code now

Free, no sign-up, and it never expires. Everything runs in your browser.

Open the generator

Keep reading