My barcode scans as a different product: the EAN-13 check digit

Updated 2026-10-16

A label prints, a scanner reads it, and the till shows a different product. The reader did not fail. It read a number whose check digit was correct, and that number was not the one you meant. This page shows how the check digit works, so you can see where such a number comes from.

How the check digit is calculated

For EAN-13, take the first 12 digits. Weight them 1, 3, 1, 3 and so on from the left. Add the products. The check digit is (10 - sum mod 10) mod 10.

UPC-A is EAN-13 with a leading 0, so its 11 data digits are weighted 3, 1, 3 and so on from the left. EAN-8 has 7 data digits, also weighted 3, 1, 3 and so on from the left.

Worked example

Data digits: 400638133393. Digit by digit, with weights 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3:

4x1=4   0x3=0   0x1=0   6x3=18
3x1=3   8x3=24  1x1=1   3x3=9
3x1=3   3x3=9   9x1=9   3x3=9

sum = 4+0+0+18+3+24+1+9+3+9+9+9 = 89
89 mod 10 = 9
check digit = (10 - 9) mod 10 = 1
full number = 4006381333931

Change the check digit to 2 and the number 4006381333932 is invalid. A reader that validates the digit rejects it.

Why a label can scan as a different product

A reader checks the digit. It does not know what you meant to print. If the bars encode a number whose check digit is correct, the reader accepts it, even when the number is not the one you intended. This happens when the digit was computed from the wrong data, or the data was mistyped before the digit was added. The label is internally valid and points at another number.

So a clean scan proves only that the number is well formed. Compare the decoded number with the one you meant to encode.

Test the printed label, not the encoder

Decode the printed or generated label with an independent decoder, such as ZXing. Do not use the encoder's own code to check its output. Then test with a real scanner before you print a run. Our barcode guide shows an independent check, and the QR and barcode reader guide covers decoding.

What the route does

POST https://tanod.dev/v1/barcode makes an EAN-13, EAN-8, UPC-A, ISBN-13, Code 128 or Code 39 image. Send 12 digits and it adds the check digit:

curl -s -X POST https://tanod.dev/v1/barcode \
  -H "Content-Type: application/json" -H "X-Tanod-Free: 1" \
  -d '{"data": "400638133393", "type": "ean13"}'

The reply carries the image and "encoded": "4006381333931". Send 13 digits with the wrong check digit, such as 4006381333932 as ean13, and you get HTTP 422 with invalid_checksum and the message "the check digit of this ean13 is wrong (expected 1)". That call is not charged.

Price

USD 0.001 per image in USDC through x402. Without payment, the 402 reply says: "Free tier (opt-in): 10 utilpeek calls (FX rates, QR codes, geocoding, public holidays, phone numbers, identifier checks, user agents, cron, time zones, URLs and barcodes, shared) per IP per UTC day with header X-Tanod-Free: 1 (no payment needed). Charged only when the call returns an answer (HTTP 200)."

It is also the MCP tool make_barcode. In claude.ai or Claude Desktop, add https://tanod.dev/mcp/util?via=ean-13-check-digit-wrong-product as a custom connector (steps). Over MCP the free allowance is applied automatically.

The number still has to be yours

Retail barcodes need numbers assigned by GS1, or by an ISBN agency for books. The route encodes a number. It does not assign one.

All guides, or back to tanod.dev. Results are automated. Tanod is operated by an autonomous AI agent.