All posts

Why your QR code doesn't scan: a field diagnosis

8 min readReliabilityPrinting

FOUND?EDGES?CONTRAST?SIZE?PAYLOAD?WORK DOWN. STOP AT THE FIRST FAIL.

A code that won't scan feels random, and never is. A decoder does its work in a fixed order — find the code, fit the grid, read the data — so failures happen in a fixed order too. Work down this list and stop at the first thing that's wrong; everything after it is noise.

1. Can it be found at all?

The three big corner squares are how a scanner discovers there's a code in frame. If artwork restyled them beyond recognition, put a logo over one, or a reflection is washing one out, the phone never shows the yellow frame at all — it isn't failing to read the code, it never saw one. Cover check: all three corners present, dark, and un-clever.

FINDERS ×3 — how thecode is located at allDATA + ERRORCORRECTIONQUIET ZONE — 4 modulesof nothing, on purposeCROP THE MARGIN AND THE SCANNER NEVER FINDS THE EDGES
The decoder's dependencies, in the order it uses them: finders to locate, the quiet zone to find edges, then the data. A failure earlier in the chain masquerades as everything after it being broken.

2. Do the edges exist?

The quiet zone — the empty margin, four modules wide — is how the found code gets its boundaries. The classic kill is a layout that crops the margin or butts the code against a busy background: the file was fine, the page is not. If your code scans on its own and fails in the layout, this is almost always it.

3. Does the contrast survive a sensor?

Sensors binarise: each module becomes ink or paper, nothing between. Tone-on-tone brand palettes — gold on white, grey on cream — look premium and read as blank. Partial inversion (dark background, but the finders left dark too) confuses the polarity entirely. Dark modules on a light ground, or a completely inverted grid, both work; anything in between is gambling with light conditions.

dark on lighttone on toneinverted, wholly
What survives binarisation: strong dark-on-light, or total inversion. The middle tile is the one that demos well on a screen and dies in a dim restaurant.

4. Is it big enough for the distance?

A code scans to about ten times its width, and a printed module below half a millimetre dissolves regardless of distance. If people are squinting and stepping closer, the code is under-sized for where it lives — arithmetic covered in the sizing post, or done for your exact content by the size calculator. Note the compound case: a long URL makes a denser grid, which shrinks every module, which quietly demands a bigger print than last time's artwork needed.

5. Does the payload behave?

Sometimes the scan works and the result doesn't: a URL without https:// opens as a text search, a Wi-Fi string with an unescaped semicolon in the password fails silently, a vCard with swapped name fields imports backwards. The camera did its job; the payload was wrong. Every free generator here encodes the format correctly per type, which removes this class entirely.

Measure instead of guessing

  • Upload the artwork to the scannability checker — it decodes at shrinking sizes and tells you the real margin, or that nothing decodes at all (which points you at steps 1–3).
  • Scan a printed proof with the in-browser scanner under the worst realistic light.
  • Rebuilding it? The design rules keep brand styling on the safe side of every step above.

And one operational note: if an old dynamic code stopped working while the grid itself is fine, the print isn't the suspect — the destination or the vendor is. That failure mode, and how to insure against it, is its own subject.