It worked on your screen. It worked when you tested it on your phone. Then you printed two hundred of them and nothing happens when anyone points a camera at it. Here is what went wrong, in millimetres.
A QR code fails on paper for one of four reasons, and they are not equally likely:
All four look identical to the person holding the phone: nothing happens. They need completely different fixes, which is why guessing is expensive.
A QR code is not just the pattern of squares. The specification requires a margin of blank space around it — four modules wide on every side, a module being one of the small squares. That margin is not decoration. It is how a scanner finds the code in the first place.
A phone camera does not see a page the way you do. It looks for the three square finder patterns in the corners, and it identifies them by the ratio of dark to light runs as it scans across. Press a coloured panel, a photograph, or a border right up against the edge of the code and that ratio breaks. The code is still perfectly intact and still perfectly readable in principle. The scanner simply never locates it.
A camera needs to resolve each individual module, not just see the code. In practice that means roughly three and a half camera pixels per module, and that requirement is what sets the real minimum size — not how the code looks on screen.
Two thresholds matter. Below 0.40 mm per module a consumer printer cannot reliably place the squares and a phone cannot resolve them; that is a hard floor. Below 0.50 mm it will scan from close up on a good printer but has no margin left for ink spread, a cheap camera, or dim light. And independently, a code smaller than about 20 mm square is hard for a phone to lock focus on at any distance.
Module size depends on how much you encoded. A short link needs 25 modules across; a long one with tracking parameters needs 33 or more. The same printed square gets harder to scan the more you put in it. Shortening the URL is often the cheapest fix available.
| Printed size | Short link (25 modules) | Longer link (33 modules) | Suits |
|---|---|---|---|
| 15 mm | 53 cm | 40 cm | too small to focus on reliably |
| 20 mm | 70 cm | 53 cm | business card, held in hand |
| 25 mm | 88 cm | 67 cm | invitation, postcard |
| 30 mm | 106 cm | 80 cm | flyer, letter page |
| 40 mm | 141 cm | 107 cm | small poster on a wall |
| 50 mm | 176 cm | 133 cm | poster read from across a room |
| 75 mm | 264 cm | 200 cm | shop window, noticeboard |
| 100 mm | 352 cm | 267 cm | banner, large format |
This one is almost always a design decision. The code gets recoloured to match a palette — navy on teal, brown on cream, white on a photograph — and it still scans on a bright backlit screen, so it looks fine. Paper has no backlight, ink spreads slightly into the fibres, and the gap between light and dark narrows further.
The measure used in print verification is symbol contrast: the difference between the reflectance of the light areas and the dark ones. Note difference, not ratio — a code printed in two dark colours can look like a strong contrast ratio while having almost no actual separation.
| Grade | Symbol contrast | In practice |
|---|---|---|
| A | 70% and above | black on white, no concerns |
| B | 55 – 70% | a dark colour on white, fine |
| C | 40 – 55% | works on clean paper, no margin |
| D | 20 – 40% | unreliable once printed |
| F | below 20% | will not scan |
Two other contrast traps. Inverting the code — light squares on a dark background — is legal in the specification but many scanners handle it poorly, so avoid it on anything that matters. And placing a code over a photograph fails even when the average contrast looks acceptable, because the background varies underneath the modules.
QR codes carry error correction, so a code can lose some modules and still decode. That resilience hides damage until it runs out. A code that was screenshotted, resized to an odd dimension, saved as a low-quality JPEG, or exported from a slide deck may arrive at the printer having already spent most of its error correction — and then ink spread uses the rest.
If a code decodes but reports little unused error correction, it is not healthy, it is surviving. Always place the original code file rather than a copy of a copy, and never re-save a QR code as a JPEG — the compression puts soft halos on exactly the sharp edges the scanner depends on. Use PNG or vector.
Check where the code actually goes. AI image tools generate QR codes that encode
placeholder addresses — example.com and its relatives — and the code scans
perfectly while leading nowhere. Scan the finished file yourself and read the address it
opens, every time, before it goes to print.
PrintSanity decodes the codes in your artwork, measures them in millimetres against the size you intend to print, then prints them in simulation at plain-paper quality and scans them back to see whether they survive. It will tell you which of the four problems you have, and repair the code for you if it can.
Check a file