QR code not scanning? Six fixes that solve 95% of cases

Six root causes — contrast, size, error correction, glare, damage, payload mismatch — and the concrete fix for each when your QR code is not scanning.

May 11, 2026 17 min read Linked.Codes Updated May 14, 2026
QR code not scanning? Six fixes that solve 95% of cases

A QR code not scanning almost always traces back to one of six root causes, and every one of them has a specific fix that takes minutes once you know what to look for. The phone camera isn't broken, the app isn't broken, the standard isn't broken — something about the printed code or the conditions you're scanning it under is outside the band where the decoder can recover the data. Most "why is my QR code not scanning" posts list ten generic tips and leave you to guess. This one walks the six failure modes in order of how often they actually show up, with the diagnostic that tells you which one you're looking at and the fix that ends the problem.

The order matters. Contrast and module size at print scale together account for somewhere between 60% and 75% of the failures we see come through support. Error correction mismatch and damaged print are the next layer. Glare and payload-mismatch problems sit at the bottom because they're rarer, but when they hit they're often the trickiest because they look like the code "just doesn't work" without an obvious cause. Walk the list top to bottom and you'll find your culprit before the third item in roughly two cases out of three.

A QR code not scanning is almost always one of six things

The order matters because the failure modes have very different fix cost. Contrast is a five-minute colour swap; a damaged print is a reorder. Module size is a layout change; a payload mismatch is a redirect tweak. Knowing which of the six you're dealing with tells you whether the fix is fast or slow before you commit time to it.

Cause 1 — Contrast is killing 60% of failed scans

Phone-camera QR decoders work by sampling the centre of each module and asking one question: darker than threshold, or lighter than threshold? When the dark modules and the light background sit too close together on the luminance scale, the decoder can't make that call cleanly. Some samples land on one side of the line, some on the other, and the recovered grid is full of bit errors that overflow the redundancy budget.

ISO/IEC 18004 specifies a minimum reflectance contrast, and the practical translation in WCAG terms is roughly 3:1 — that is, the dark colour reflects roughly a third as much light as the light colour. The trouble is that 3:1 is a floor, not a target. Phone cameras process under varying exposure, sometimes off-axis, often through indoor light that throws colour casts onto the page. A 3:1 design that scans on your monitor often fails on a printed flyer at arm's length under fluorescent light. The comfortable target is 7:1 or higher; black-on-white sits at 21:1 and is the gold standard for a reason. Schools that print at scale and can't reorder hit this floor more often than anyone, which is why the classroom-equity fallback and pre-flighting routine documented for school QR runs reads like a contrast manual with a different cover. A useful sanity check before reordering print: re-render the same payload at 7:1 contrast in the public QR designer and scan from the same angle under the same light — if the new version scans, contrast was the culprit and you don't need to keep diagnosing.

QR code not scanning — contrast ratio comparison Contrast ratios that scan vs ratios that don't 21:1 PASS black on white 12:1 PASS deep navy on cream 3.4:1 RISKY mid-grey on white 2.4:1 FAIL navy on light blue Aim for 7:1 or better. The 3:1 floor passes the spec but fails in real lighting.
Four contrast configurations and how they behave on a phone camera. The two on the right look fine on screen — they fail on print under indoor light.

The diagnostic is fast: open a free contrast checker (any WCAG-compliant tool will do), drop in your foreground and background hex values, and read the ratio. Below 4.5:1 you're in the danger band; below 3:1 you're broken. The fix is mechanical — push the dark colour darker until you cross 7:1. Sometimes that's a 10% luminance shift and the brand team won't even notice. Sometimes you have to fight for it. Either way, contrast is non-negotiable. A QR code with great contrast and a mediocre logo always beats the inverse.

One trap to avoid: red-on-grey looks bold to the eye but the camera's red channel is the noisiest, and decoders weight green more heavily. If you're using a brand red, switch to deep red or burgundy to push the green-channel reading darker. Same trap with blue-on-grey — phone cameras are weakest on the blue channel, and what reads as "dark blue" to a designer reads as "mid-grey" to the QR decoder.

Cause 2 — The code is too small at print scale

The second-most-common failure isn't a colour problem; it's a geometry one. QR codes encode data in a grid of modules — 21×21 for the smallest version, scaling up to 177×177 for the largest. Every module needs enough printed area that a phone camera, at the scan distance you actually use, can resolve it. The floor is roughly 1.5 pixels per module at the camera sensor. Below that, the decoder loses too many samples and the redundancy budget gets blown.

The rule of thumb that survives contact with reality: minimum side length in mm = scan distance in mm ÷ 30. A code on a flyer scanned from 30cm needs at least 10mm side length; in practice 18mm is the comfortable floor because real readers don't always scan from the optimal distance. A code on a poster scanned from 2m needs at least 67mm. A code on a billboard scanned from 30m needs at least 1m. Designers reflexively shrink QR codes to fit a layout — you can't. The code is the message, not a decoration.

The diagnostic is simple: measure your printed code with a ruler, work out the modules per side from the encoded payload (a 30-character URL at level M produces a 25×25 grid; a 200-character URL at level L produces a 53×53 grid), and divide. If you've got fewer than 0.7mm per module, you're below the floor for arm's-length scanning. The fix is twofold — either enlarge the code, or reduce the payload so the grid gets coarser at the same physical size. The second option is why dynamic short links matter for print. A 200-character tracking URL becomes a 30-character redirect, and your modules grow by roughly 60% in printed size at the same physical footprint.

Print size floor by scan distance Minimum printed side length by scan distance (1/30 rule) SCAN DISTANCE MINIMUM SIDE LENGTH TYPICAL CONTEXT 30 cm (arm's length) 10 mm (18 mm safe) flyer, label, business card 1 m (table sign) 33 mm (45 mm safe) menu stand, shelf talker 2 m (poster on a wall) 67 mm (90 mm safe) A3 poster, retail signage 5 m (large poster) 167 mm (220 mm safe) bus stop, lobby display 30 m (billboard) 1000 mm (1.3 m safe) highway, building wrap
The 1/30 rule converts your worst-case scan distance into a printed side-length floor. The "safe" column adds a 35% margin for off-distance scans, lower-end phone cameras, and uneven lighting.

If shrinking the layout is non-negotiable, your real lever is payload reduction. A QR carrying a 30-character short URL is dramatically smaller per module than the same QR carrying a 200-character UTM-laden tracking URL. We covered the underlying math in the QR scanability score post — the modules-per-side count is what determines whether your code stays inside the printable-size envelope at all.

Cause 3 — Error correction is too low for the conditions

The third cause is where the redundancy budget runs out. QR codes carry built-in error correction at four levels — L (≈7%), M (≈15%), Q (≈25%), and H (≈30%) — meaning that fraction of the printed area can be missing or misread and the decoder still recovers the original data. Most generators default to M without explaining the trade-off, and that default works for clean indoor print. It does not work for outdoor, packaging that's been through a warehouse, codes with a logo overlay, or surfaces that age. If your code is failing in any of those contexts and the contrast is fine and the size is right, error correction is your suspect.

The diagnostic is to look at where the code is deployed and ask: how much of the surface is likely to be obscured, scratched, faded, or covered? If the answer is over 7%, level L will fail. Over 15%, level M fails. The honest framework is to pick the lowest level that survives the realistic worst case. Outdoor exposure where dust, sun-fading, and minor scratches are inevitable wants level Q at minimum. A logo overlay above 15% of the code area wants level H regardless of other conditions. We unpacked the full level picker in the error correction post, including the cases where higher correction backfires by making the modules too small.

Error correction capacity per ISO/IEC 18004 Recoverable area at each error correction level Level L (low) 7% screen-only, pristine glossy print Level M (medium) 15% most generators default — good for clean print Level Q (quartile) 25% outdoor, packaging, small logo overlap Level H (high) 30% large logo, harsh wear, near-minimum size Higher levels carry more redundancy modules, which makes the code denser. Pick the lowest level that survives your worst-case conditions.
The four ISO/IEC 18004 error-correction levels and the practical context each one is designed for. M is the soft default; jump to Q for any outdoor or logo-bearing code.

The mistake people make is reflexively cranking error correction to H "to be safe." H costs you density — for the same payload, an H-level code uses roughly twice the module count of an L-level code. Higher density at the same physical print size means smaller modules, which feeds straight back into the cause-2 problem. The right move is to match the level to the failure mode, not max it out and hope.

Cause 4 — Glare and reflectance are eating the read

Glossy paper, foil stock, lacquer finishes, and the screen of the phone you're scanning from a magazine page all share a problem: under angled overhead lighting, a glare patch falls across part of the code and the camera's auto-exposure adapts to the bright spot, which throws the dark modules elsewhere into noise. The code looks fine to the human eye — you can read every module — but the camera's sensor is saturated in one zone and underexposed in another, and the decoder can't recover the grid.

The diagnostic is rotational: pick up the printed item, tilt it back and forth under the light source you're scanning under, and watch for the glare patch travelling across the code. If you can see it, the camera can definitely see it. The fix has two layers. First, change the surface — matte stock, matte varnish, or a dedicated matte panel under the code. Second, change the angle — if the code is on glossy packaging that can't be respec'd, instruct the scanner (in print copy near the code) to tilt the package, not the phone. A 15-degree off-axis tilt is usually enough to push the glare zone outside the code area.

A failure mode that sits adjacent to glare but kills scans for a different reason is destination-side rather than print-side: the QR fires fine, the redirect lands, and then the page that loaded can't actually play what was promised. The clearest case is video — autoplay blocked on iOS Safari, mobile data too slow for the first chunk, the host taking the video down between print and scan. The autoplay + analytics-gap walkthrough for QR codes pointing at video covers the destination-side failures that look identical to a scan failure to the reader but happen after the camera has already done its job.

Glare on a glossy QR code — what fails and what fixes Glare patch on glossy stock — failure and fixes FAIL glare wipes out modules FIX A matte stock — no glare FIX B tilt 15° — glare moves off
Glare on glossy QR codes is fixable two ways: change the surface to matte, or instruct the scanner to tilt the print. Either pulls the saturated patch off the modules.

A subtler glare problem is the screen scan — someone trying to scan a QR code that's displayed on another phone or a TV screen. The screen's own backlight creates a uniform-brightness rectangle that the camera reads as ambient, and the dark-vs-light contrast threshold often shifts wrong. The fix here isn't on the production side — it's to render the on-screen QR with extra padding (more quiet zone) and at higher contrast than you'd use for print. White-on-pure-black on a screen scans more reliably than the same code printed.

Cause 5 — The print is physically damaged

A QR code that worked on day one and stopped working on day thirty has almost always picked up enough physical damage that the redundancy budget is exhausted. Coffee splashes, fingernail scratches, fading from UV exposure, label adhesive bleeding into the print, ink rub-off where stickers stack against each other in shipping — all of these chip away at the recoverable area until the decoder can't reconstruct the payload.

The diagnostic is visual. Compare the code to a fresh copy of the same artwork. If you can see ten or more modules that have changed value (white turning grey, black fading or smudged, partial occlusion from dirt), you're at or beyond the recovery limit at level M. If the code was printed at level L, you've been over the limit since five modules went bad.

The fix has two paths depending on what you're optimising. If the code is dynamic — pointing at a redirect URL you control — you don't need to reprint the data, you need to reprint the code. The destination is unchanged; the printed sticker is what's gone. Order replacements and apply over the top. If the code is static, the URL is baked into the modules and a damaged code is genuinely broken; you need a new design and a new print run, and that's a good reason to switch to dynamic for the next round. For WiFi credentials specifically, dynamic WiFi QR codes cover the rotation-without-reprint pattern in detail.

A point worth flagging for anyone planning a deployment that will see real wear: jump the error correction one level above what you'd otherwise pick. The extra redundancy buys you weeks or months of additional life under field conditions. We dig into the trade-offs around outdoor durability in the QR codes for outdoor advertising post — the framework there transfers cleanly to any high-wear print application.

A QR code with no contrast, no margin on size, and no error-correction headroom is a printed gamble. Build with all three and the only way to break the code is to physically destroy it.

Cause 6 — The encoded payload doesn't match what the scan target expects

This one's the rarest of the six but the most confusing when it hits, because the code scans cleanly — the phone reads the encoded data — and then nothing useful happens. The decoder did its job; the application receiving the decoded text doesn't know what to do with it.

Two flavours of payload mismatch show up most often. First, you encoded a URL that the destination doesn't serve any more — domain expired, redirect chain broken, target page deleted. The scanner opens the browser, the browser shows an error, and the user blames the QR. Second, you encoded a non-URL payload — a vCard, a wifi credential, a calendar event — in a format the scanning app doesn't recognise as that type. The contact-card flavour of this — a QR that should automatically add the contact to the phone but lands as a wall of raw text instead — is unpacked end-to-end in QR code to add contact to phone. Some QR readers only handle URLs, some handle URLs plus a few special schemes, very few handle every payload type the QR specification supports.

The diagnostic is to scan the code with a generic QR reader (the one built into iOS Camera or Google Lens — the device-by-device scan walkthrough covers how to do this on every common phone) and read the raw decoded text. If the text matches what you encoded — and the encoded payload is a URL — then load the URL manually in a browser to confirm the destination is alive. If the text matches and it's a non-URL payload, you've got a format support problem; the fix is either re-encoding as a URL that points at a landing page (which works in every QR reader) or accepting that some scanners will fail. For dynamic short links pointing at QR-friendly destinations, the redirect target is what you control — and what you're encoding never has to change.

Will my QR scan? Pre-flight check

SCANS

    Plug in your numbers. The widget runs the same checks against the same thresholds discussed above and tells you which of the six causes is going to bite first. It's intentionally conservative — the verdict band is calibrated to where real-world scan rates start dropping below 95%, not to where the spec technically allows the read to succeed.

    A pre-flight that catches all six before print

    The cheapest place to fix a QR code not scanning is before any of it ships to a printer. Run this five-step pre-flight on every code that's heading to a paid print run:

    1. Contrast check. Drop foreground and background hex codes into a WCAG contrast checker. 7:1 or higher gets a green light; 4.5:1 to 7:1 is yellow; below 4.5:1 redo it.
    2. Size sanity. Multiply your worst-case scan distance by 1/30. Your printed side length should be at least that, plus a 35% safety margin. If you're at 12mm aiming for arm's-length scans, you're broken.
    3. Error correction match. Indoor, clean print, no logo: M is fine. Outdoor, packaging, or any logo overlay above 15%: jump to Q or H.
    4. Surface check. Glossy stock without a matte panel for the code is a scan failure waiting to happen. Specify matte for the QR area or move to satin.
    5. Live print test. Print one proof at the actual final size, on the actual final paper, and scan it from the actual final distance — on at least three different phones, in at least three different lighting conditions. If any combination fails first try, the design isn't ready.

    The whole pre-flight takes fifteen minutes. The cost of skipping it is a five-figure reprint when the campaign launches and the scan rate is half what you projected. We've seen the math go bad more than once; the calibration above is what we now use internally before signing off any QR for high-volume deployment. The full design checklist is in the design-a-custom-QR post, and the underlying scanability scoring is in the scanability score post.

    Try the QR designer — it ships round modules at 105% by default, the size most prints need.

    Open the editor

    Where each fix lives in the editor

    If you're already designing inside Linked.Codes, every cause has a knob and a warning. The contrast check fires when the foreground/background ratio drops below 4.5:1, with a hard error below 3:1. The print-size simulator runs your modules-per-side count against your stated print size and lights up yellow when modules drop below 0.7mm or red below 0.5mm. The error-correction picker auto-bumps to H whenever a logo overlay crosses 15% of the code area. The surface-finish field is text-only, but the scanability score weights it into the recommendation when you flag the code as glossy.

    The principle is to prevent the broken code from ever reaching the export step. A QR you can't print is one you can't ship; the editor's job is to surface every reason that might be true while you can still fix it. The full doc walkthrough is in the QR codes documentation, including how to wire dynamic destinations so a single printed code can point at a different URL next month without a reprint.

    Why is my QR code not scanning even though it looks fine?

    Almost always one of three things: contrast that's too low for a phone camera even though the design looks bold to your eye, a print size that's too small at the scan distance you're using, or glare from glossy stock that's wiping out a strip of modules. Run the pre-flight in this post — the verdict will land on the broken cause within a minute.

    What's the minimum contrast ratio for a QR code?

    ISO/IEC 18004 specifies a minimum reflectance contrast that translates to roughly 3:1 in WCAG terms. That's a floor, not a target. Aim for 7:1 or better to handle real-world lighting; 21:1 (black on white) is the gold standard.

    How small can I print a QR code before it stops scanning?

    The 1/30 rule: minimum side length in mm equals scan distance in mm divided by 30. Arm's length (30 cm) needs at least 10 mm of side, with 18 mm being the comfortable floor. Below that, you're trading reliability for layout. Shortening the encoded URL lets you stay smaller without losing scan rate.

    Should I always use error correction H to be safe?

    No. H roughly doubles the module count for the same payload, which makes the printed grid denser and harder to scan at small sizes. Pick the lowest level that survives your worst-case conditions. M is a defensible default for clean indoor print; Q for outdoor or any logo overlap; H only for large logos or harsh wear.

    Why does my QR code scan on screen but not when I print it?

    Three usual suspects: contrast was high on screen but lower in print (most CMYK reproductions lose 5–15% of the displayed contrast), the print size came out smaller than the screen preview implied, or the printer trimmed the quiet zone (the white margin around the code). Print one proof and field-test before the full run.

    Can a damaged QR code still be scanned?

    Up to the error correction level — 7% at L, 15% at M, 25% at Q, 30% at H. Beyond that the decoder returns a hard failure. There's no partial recovery. If the code's worn past the recovery threshold, the fix is to reprint; if it's a dynamic code, the URL behind it is unchanged, so only the sticker needs replacing.

    What if the code scans but the link is broken?

    That's a payload mismatch, not a scan failure. The decoder did its job; the destination URL is dead, malformed, or pointing somewhere the receiving app doesn't handle. The fix depends on whether the code is static (you have to reprint with a new URL) or dynamic (you update the redirect destination behind the existing code without touching the print).

    Sourcesshow citations

    Try it on your own domain

    Branded short links and dynamic QR codes, on your subdomain or your own domain. One-time purchase, no per-click fees.