X Xerobit

QR Code Error Correction — L, M, Q, H Levels Explained

QR codes have four error correction levels: L (7%), M (15%), Q (25%), H (30%). Higher levels allow more damage tolerance but create larger/denser codes. Learn which level to...

Mian Ali Khalid · · 4 min read
Use the tool
QR Code Generator
Generate QR codes for URLs, text, Wi-Fi, contact cards. Custom size, colors, error correction. Download as PNG or SVG. 100% client-side.
Open QR Code Generator →

QR code error correction allows damaged or partially obscured codes to still scan. The four levels trade off between damage tolerance and code density (size).

Use the QR Code Generator to generate QR codes with any error correction level.

Error correction levels

LevelNameData recoveryUse case
LLow7%Clean environments, digital display
MMedium15%General purpose (default)
QQuartile25%Printed labels, logos embedded
HHigh30%Industrial environments, outdoor signage

“Data recovery” means the percentage of the codewords that can be restored even if that portion is damaged, dirty, or obscured.

How error correction affects QR size

Higher correction levels store more redundant data, requiring more modules (black/white squares):

Same data ("https://example.com") at different levels:
Level L: 25×25 modules (Version 2)
Level M: 25×25 modules (Version 2)
Level Q: 29×29 modules (Version 3)
Level H: 33×33 modules (Version 4)

The code gets physically larger (denser) with higher correction.

Choosing the right level

L (7%) — Use when:
- Code displayed on screen (no physical damage risk)
- Need maximum data in minimum space
- Controlled clean environment

M (15%) — Use when:
- General purpose printed QR codes
- Standard business cards, posters
- No embedded logo needed

Q (25%) — Use when:
- Logo or design element will overlay the center
- Slightly degraded print quality expected
- Product packaging with wear

H (30%) — Use when:
- Industrial/outdoor use (dirt, moisture, partial damage)
- Very small printed size
- Guaranteed scanning in harsh conditions
- Custom design with significant overlaid artwork

Logo overlay and error correction

A popular QR code design embeds a brand logo in the center. This works because:

  1. The center overlays ~10-15% of the code
  2. Error correction can recover that data
  3. Level Q or H ensures enough redundancy
// JavaScript: generate QR code with center logo using qrcode npm:
import QRCode from 'qrcode';

async function generateQRWithLogo(text, logoUrl) {
  const canvas = document.createElement('canvas');
  const size = 300;
  
  await QRCode.toCanvas(canvas, text, {
    errorCorrectionLevel: 'H',  // High for logo overlay
    width: size,
    margin: 2,
  });
  
  const ctx = canvas.getContext('2d');
  const logo = new Image();
  logo.src = logoUrl;
  
  await new Promise(resolve => logo.onload = resolve);
  
  const logoSize = size * 0.2;  // 20% of QR code
  const logoX = (size - logoSize) / 2;
  const logoY = (size - logoSize) / 2;
  
  ctx.fillStyle = 'white';
  ctx.fillRect(logoX - 4, logoY - 4, logoSize + 8, logoSize + 8);
  ctx.drawImage(logo, logoX, logoY, logoSize, logoSize);
  
  return canvas.toDataURL('image/png');
}

Reed-Solomon error correction

QR codes use Reed-Solomon error correction codes, the same algorithm used in CDs and DSL:

Reed-Solomon overview:
- Data is treated as polynomial coefficients
- Generator polynomial derives error correction codewords
- Can detect and correct errors up to (n-k)/2 symbols
  where n = total codewords, k = data codewords

Example for Level M, Version 1 (21×21):
- Total: 26 codewords
- Data: 16 codewords  
- EC: 10 codewords
- Can correct up to 5 symbol errors

Generating QR codes with specific levels in code

// qrcode library (npm):
import QRCode from 'qrcode';

// SVG output, Level H:
const svgString = await QRCode.toString('https://example.com', {
  type: 'svg',
  errorCorrectionLevel: 'H',
  margin: 2,
  width: 256,
  color: {
    dark: '#1e293b',
    light: '#ffffff',
  },
});

// PNG buffer, Level M:
const buffer = await QRCode.toBuffer('https://example.com', {
  errorCorrectionLevel: 'M',
  width: 512,
});
# Python: qrcode library
import qrcode

qr = qrcode.QRCode(
    version=None,  # auto-select
    error_correction=qrcode.constants.ERROR_CORRECT_H,
    box_size=10,
    border=4,
)
qr.add_data('https://example.com')
qr.make(fit=True)

img = qr.make_image(fill_color='black', back_color='white')
img.save('qr_high.png')

Related posts

Related tool

QR Code Generator

Generate QR codes for URLs, text, Wi-Fi, contact cards. Custom size, colors, error correction. Download as PNG or SVG. 100% client-side.

Written by Mian Ali Khalid. Part of the Dev Productivity pillar.