Experiment

Why a QR Code Will Not Scan: Tests of Margin, Contrast, Data Length, and Error Correction

We changed QR margin, size, color contrast, data length, and error-correction level one factor at a time, then recorded what decoded and what failed.

The quickest fixes for a QR code that will not scan are usually not camera settings. Check the empty border around the code, the contrast between the modules and background, the amount of data inside, and the size people actually see on screen or paper.

A QR code stores information in a grid of small squares. A long address needs a denser grid at the same physical size. Nearby decoration can make the boundary harder to locate, while pale colors leave less separation once blur, glare, or print noise is added.

For this experiment, we generated short and long URLs and changed margin, size, contrast, and recovery level one factor at a time. A software decoder provides a controlled comparison rather than a universal phone-camera success rate.

Fix margin and contrast before adding visual decoration

The empty border is a functional part of the code

With edge clutter added, a four-module margin decoded while the no-margin version failed.

More data makes the same-sized code denser

The short URL decoded at 96 px, but the long URL failed at 96 px and decoded at 256 px.

Higher error correction is not a universal fix

It can recover some damage, but may add density, so margin, contrast, and usable size still come first.

We changed one practical condition at a time

  1. 1

    On September 10, 2026, we generated a short URL, https://toolit.kr/, and a longer test URL. The baseline used black modules, a white background, 256 px, a four-module margin, and error-correction level M.

  2. 2

    The codes were generated with qrcode 1.5.4 and decoded with jsQR 1.4.0. A result counted as successful only when the decoded string exactly matched the full source string.

  3. 3

    For the margin pair, identical black clutter was placed outside each code. For the contrast pair, the same deterministic pixel noise, up to plus or minus 56 brightness levels, was added. The data-length pair kept the displayed pixel size unchanged.

  4. 4

    For error correction, the same central white square covered 16 percent of the width and height of codes made at L, M, Q, and H. This is a simple obstruction model, not a claim that covered area directly equals the published recovery percentage.

  5. 5

    Each result is one decode of a stationary digital image. It does not include camera focus, glare, viewing angle, print spread, or distance, so the useful finding is the direction of each comparison rather than a universal threshold.

A clean short code decoded at small sizes, but a denser code did not

The short black-on-white code decoded at 256, 96, 64, and 48 px. That does not establish 48 px as a safe production size: the source was perfectly sharp and had none of the blur or print spread found in a real camera workflow.

The long URL failed at 96 px while the short URL succeeded at the same size. What matters is not only the outer width but whether each individual square remains distinct.

Test conditionDecode resultWhat it means
Short URL · 256 px · black/white · margin 4SuccessBaseline
Short URL · 96 pxSuccessReadable as a clean digital original
Short URL · 64 pxSuccessDoes not guarantee camera or print use
Short URL · 48 pxSuccessA result for this clean decoder input only
Long URL · 256 pxSuccessThe larger image preserved dense modules
Long URL · 96 pxFailureMore data was harder at the same size

Without a quiet zone, nearby design can merge with the code

The empty border is called the quiet zone. In plain terms, it is a safety area that lets a reader locate the start and end of the QR symbol. DENSO WAVE specifies a margin four modules wide on every side.

We placed the same black bar pattern around both test images. The code with a four-module margin decoded, while the no-margin version failed. A no-margin code may still work on a clean white page, but text, borders, and artwork remove that accidental space.

Edge-clutter conditionDecode resultInterpretation
Four-module marginSuccessThe code remained separated from clutter
No marginFailureNearby marks interfered with boundary detection

Pale colors lost reliability when the same noise was added

Contrast describes how easily the foreground modules can be separated from the background. Black on white has a large brightness difference; light gray on white has a much smaller one. Under the same deterministic noise, the black code decoded and the #AAAAAA gray code failed.

A white-on-black code decoded in this software test. That does not prove every built-in camera and workplace scanner handles inverted colors equally. Dark modules on a light, plain background remain the conservative choice for broad distribution.

Color conditionResult under the same noisePractical choice
Black modules + white backgroundSuccessSafest baseline
Light gray (#AAAAAA) + white backgroundFailureIncrease the brightness difference
White modules + black backgroundSuccessVerify on target scanners before distribution

Error correction is spare information used to rebuild damage

Error correction adds recovery information so a reader can reconstruct data when part of the code is dirty or obscured. The levels rise from L to M, Q, and H. DENSO WAVE describes approximate codeword recovery of 7, 15, 25, and 30 percent. A codeword is simply a stored unit of QR data for this explanation.

With the same central square covering 16 percent of the image width and height, L failed while M, Q, and H decoded. Real damage varies by shape and location, and covering a critical finder pattern can produce a different result even at the same area.

Higher recovery can also require a denser symbol for the same content. Choosing H for a long URL on a tiny business card may make each square smaller. M is a sensible starting point for normal screen and document sharing; consider Q or H when physical dirt or partial obstruction is likely and there is enough display size.

Error-correction levelCentral square (16% of width and height)Typical decision
LFailureClean use where keeping the symbol smaller matters
MSuccessStarting point for ordinary screens and documents
QSuccessPrinted material likely to be marked or partly covered
HSuccessMore recovery margin when sufficient size is available

A practical order for fixing a QR code that will not scan

Change one item at a time in this order. It is faster than repeatedly raising error correction without knowing what caused the failure.

StepCheckAction
1Empty border on all four sidesKeep text, frames, and artwork at least four small modules away
2Foreground/background separationUse near-black modules on a near-white solid background
3Amount of stored dataRemove tracking text and use a shorter URL
4Visible size of each moduleEnlarge the code and use the original PNG or SVG instead of a screenshot
5Screen or print conditionAvoid glare and folds; reprint if edges have spread
6Pre-release checkTest at the expected distance with two different phones

Scope and limits of this experiment

This was a software-decoding test: qrcode 1.5.4 generated each symbol, Chrome rasterized it, and jsQR 1.4.0 read the pixels. Each condition produced one fixed result, not a phone-model success rate or a minimum print-size standard.

The edge clutter, noise, and central cover are simple models designed to isolate variables. Real camera results combine focus, angle, motion, screen brightness, paper, and printing. Do not treat the 48 px success or the central square covering 16 percent of the width and height as a production specification.

For anything distributed publicly, display or print the final asset at its intended size and material, then scan it at the expected distance with at least two different phones.

Official documentation used for this analysis

Start with a four-module margin, strong contrast, and shorter data

A QR scanning problem rarely has one universal size answer. In this test, the presence of a four-module margin beside edge clutter, black versus pale gray under the same noise, and short versus long content at the same 96 px separated success from failure.

Clear all four sides, use dark modules on a light background, shorten the stored address, and give the symbol enough room. Error correction is a backup against damage, not a substitute for margin and contrast. The final check should always use the real display or print at the intended distance on more than one phone.