Why Some QR Codes Don't Scan: A Field Diagnostic Guide

When a QR code fails to scan, the cause is almost always one of nine things. Walk through them in order and you'll fix nearly every code that fails.

Rehan Haider
By Rehan Haider
May 9, 2026
Why Some QR Codes Don't Scan: A Field Diagnostic Guide

When a QR codeA 2D matrix barcode that encodes data in a square grid of black and white modulesA single black or white square in the QR grid. The number of modules per side scales with the QR versionThe size of a QR code, numbered 1 (21×21 modules) through 40 (177×177). Higher versions store more data but require more printed space. Read more →, from 21×21 modules for version 1 up to 177×177 for version 40. Read more →. Read more → fails to scan, there’s a temptation to call it “buggy” and move on. In practice, almost every scan failure I’ve debugged in the wild traces back to one of nine specific causes, in roughly this order of frequency. This post is the diagnostic walkthrough I run when someone tells me their code “isn’t working.”

Run through the list in order. The earlier items are cheaper to test and account for the majority of failures. By item six or seven you’re into the long tail.

Nine causes of QR scan failure, by category Three-column diagnostic compass grouping nine causes of QR scan failure. Physical and visual issues sit on the left, network and destination issues in the middle, and device and content issues on the right. Nine causes of QR scan failure, by category Start in the column where the symptom lives Physical / Visual Too small for distance Low contrast Missing quiet zone Print damage or wear Network / Destination Broken destination URL Slow redirect chain Code scans, but landing never resolves Device / Content Logo too big for ECC Phone-specific quirk Wrong content type
Diagnostic compass: locate your symptom in the matching column first. The Physical column is where the bulk of real-world failures land, so test those before chasing network or device causes.

1. The code is too small for the intended scan distance

This accounts for roughly half the failures I diagnose. The code looked fine on a designer’s monitor at 300% zoom and ended up at a size the camera physically cannot resolve from the user’s hand position.

The check: measure the printed code’s width and the typical scan distance. Divide. If the ratio is greater than roughly 1:10 (one centimetre of code per ten centimetres of distance), the code is too small. Common offenders: business cards held at arm’s length, restaurant table tents read by guests across a four-top, and posters meant to be scanned from across a room.

The fix: print bigger, or move the code closer to the user. There’s no software trick that gets around physics — the camera needs enough modules in its field of view to decode.

2. The contrast between modules and background is too low

Phone cameras need a clean step from dark to light to detect modules. Brand-friendly grey-on-grey, dark-blue-on-charcoal, or pastel-on-cream codes regularly fail because the contrast ratio drops below what scanners reliably handle.

The check: load a photo of the code into a contrast-ratio tool (or just eyeball it next to high-contrast reference). Anything below 4.5:1 is a problem; below 3:1 is broken. Modules should be the darker element — light-on-dark works on most devices but still fails on a meaningful percentage of older Android scanners.

The fix: increase contrast, or accept the failure rate. There’s no in-between. The deeper guidance on safe colour combinations is in the colored QR code post.

3. The quiet zone is too tight or absent

The four-module margin around every QR code isn’t decorative. Scanners use it to lock onto the finder patternsThe three large squares in the corners (top-left, top-right, bottom-left) of every QR code. Scanners use them to detect a QR in the camera frame, lock onto it, and determine its orientation. Read more →, and without it they often can’t tell where the code starts. Designers crop quiet zonesThe unprinted margin of at least four modules' width that must surround every QR code. Read more → aggressively to fit tight layouts; the code looks “clean” and stops scanning.

The check: look at the four edges of the printed code. Is there an unprinted margin equivalent to at least four module widths? If you can see other ink — a border, body copy, a brand mark — within that margin, the quiet zone is compromised.

The fix: restore the margin. Treat it as part of the code, not surrounding whitespace. Move neighbouring elements out, even if it means the layout breathes more than the designer wanted.

4. The destination URL is broken or has changed

This one I almost forgot to include because it feels too obvious — and yet it’s responsible for an enormous share of “not working” reports. The user scans, the camera reads the code, and the resulting URL is dead. From the user’s view this is identical to the code “not scanning.”

The check: scan the code yourself, copy the resulting URL out of the scanner’s preview, and paste it into a desktop browser. If the URL returns a 404, a redirect loop, or a generic “this domain is for sale” page, the QR did its job — the destination broke.

The fix: depends on whether the code is static or dynamic. Static codes can’t be edited; the URL has to be brought back into existence on the destination side, or the code has to be reprinted. Dynamic codes can be repointed in the redirect dashboard. This is exactly the trade-off static vs dynamic QR codes walks through in detail.

5. The redirect chain is too long or slow

A code that “doesn’t work” might actually scan fine — the camera reads it, the redirect resolves, and then the page takes 12 seconds to render on weak cellular. The user closes the browser before the destination appears and reports that “the QR didn’t work.”

The check: scan the code on a deliberately throttled mobile connection (Chrome DevTools network throttling to “Slow 3G” is a fair approximation). Time the full path from scan to first meaningful paint. Anything over 4-5 seconds is in failure territory for impatient users.

Also: count the redirect hops with curl -ILs <encoded_url>. More than one hop between the encoded URL and the final destination is asking for trouble.

The fix: collapse the redirect chain to a single hop, and optimise the destination page weight. The QR code itself isn’t the problem; the path it points down is.

6. The logo or design overlay is too large

A logo placed in the centre of a QR code obscures modules. The error-correction algorithm can recover some of those obscured modules, but only up to the configured error-correction level — 7%, 15%, 25%, or 30% depending on the level. A logo larger than the tolerance creates intermittent failures: scans succeed sometimes, fail other times, depending on lighting and angle.

The check: estimate the logo’s coverage as a percentage of the code’s total area. If it’s above 25-30%, the logo is too big. If the code was generated at level L or M (the defaults in many tools), the threshold drops to 7-15% — which most “branded” codes blow past.

The fix: shrink the logo, or regenerate the code at level Q or H with the same logo. The full-fidelity guide is the QR code with logo post.

7. Physical damage, dirt, or surface artifacts

Outdoor signage fades. Stickers on packaging get scuffed. Codes printed on glossy stock catch reflections that wash out modules. Codes printed on embossed surfaces (some packaging, leather, textured paper) deform the modules’ geometry enough to break detection.

The check: look at the actual physical specimen. Is it faded? Wet? Reflective? Embossed? Has it been outdoors for a season under direct sun?

The fix: usually requires reprinting on better material. Outdoor codes need UV-resistant inks and matte laminates. Codes on packaging that gets handled need a small protective overcoat. Glossy stock should be reserved for codes that won’t be scanned in direct light.

8. Phone-specific or app-specific behaviour

iOS Camera, Google Lens, and various third-party scanner apps don’t all behave identically. The most common edge cases I run into:

  • Inverted codes (light modules on dark background) work on iOS and modern Android but still fail on some older Android scanners.
  • Very high-density codes (version 30+) sometimes fail on older phone cameras even when the physical size is correct, because the camera can’t resolve individual modules.
  • Codes with very dark backgrounds and very dark modules fail on iOS more often than Android.

The check: scan the code on at least three devices spanning iOS and Android. If one works and another doesn’t, the code is on the edge of what scanners reliably handle, and that edge will move depending on the user’s device mix.

The fix: prefer high-contrast, dark-on-light, conventional-format codes for any public-facing campaign. Reserve “creative” formats (inverted, very dense, ultra-stylised) for surfaces where you control or can predict the device mix.

9. The code was generated with the wrong content type

Once in a while, the code “scans” but doesn’t do what was intended. The most common cases:

  • A vCardA standard text format for contact information (name, email, phone, address, organization) defined by RFC 6350. Read more → QR encoded with non-standard line endings — most scanners parse it but a few save the contact with mangled fields.
  • A Wi-Fi QR with the wrong security flag (WPA instead of WPA2) — the scan succeeds, the join silently fails on some devices.
  • A mailto: URL with unencoded special characters in the body parameter — the email opens with a corrupted draft.

The check: scan the code, look at what the phone actually does next. Did it offer to add the contact / join the network / open the email? If yes, the code is functionally correct even if the user didn’t notice. If the phone fell back to “open this URL” instead of the expected behaviour, the encoding is wrong.

The fix: regenerate using a tool that emits standards-compliant payloads. The encoding details are documented in the glossary of QR code types.

A field workflow

When someone tells me a code isn’t working, I run this exact sequence:

  1. Get a photo of the actual physical code, plus the phone they’re using.
  2. Try to scan it on my own phone in good light.
  3. If my scan fails: items 1, 2, 3, 6, 7 above (physical/visual causes).
  4. If my scan succeeds and lands somewhere broken: items 4, 5 (URL/redirect causes).
  5. If my scan succeeds, theirs doesn’t: item 8 (device-specific behaviour).
  6. If everyone scans fine but the resulting action is wrong: item 9 (content type).

Almost every “broken QR code” report resolves within the first three steps. The remainder usually requires a reprint, which is why getting items 1-7 right before the press file ships is so important — see the print-ready QR code checklist and the 12 most common QR code mistakes for the upstream version of this same workflow.

If you’re shipping a lot of codes and want to monitor failures in production, the best leading indicator isn’t scan rate (which is hard to baseline) — it’s the conversion rate from scan to next action on the destination page. A drop there usually means the code is succeeding at the camera level but failing somewhere downstream. The scan-tracking guide covers how to instrument that loop, and the AI and QR codes piece has more on how the next generation of dynamic codes are starting to surface those failures automatically.

Sources

  • ISO/IEC 18004:2015 — The international standard that defines the QR symbol structure, including the four-module quiet zone requirement and the L/M/Q/H error-correction levelsOne of four settings that controls how much damage a QR code can tolerate: L (about 7%), M (15%), Q (25%), or H (30%). Read more → referenced in causes #3 and #6.
  • Denso Wave — QR Code variants — Reference from the original inventor for the QR code family, error-correction trade-offs, and version-density tables relevant to the high-density failure mode in cause #8.
  • Wikipedia — QR code — Background on scanner behaviour, contrast tolerance, and the iOS / Android scanner differences flagged in cause #8.

Ready to build your QR campaign?

Apply the same guidance from this article in the generator, then test on real devices before launch.