Which Barcodes Can Your Phone Actually Scan?
There are three different answers to "can my phone scan this barcode", and people keep giving each other the wrong one. The Camera app, the operating system underneath it, and the app you installed all support different sets of formats โ and the usual summary, that iOS is consistent and Android is fragmented, gets the barcode story almost exactly backwards.
A recurring question on the Apple support forums goes something like this: the camera scans QR codes perfectly, so why does pointing it at the barcode on a cereal box do absolutely nothing? No prompt, no banner, no result. The phone that reads a restaurant menu code from two metres away cannot see a UPC held six inches from the lens.
The answers usually offered are that the barcode is damaged, that the lighting is wrong, or that the phone needs a settings change. Occasionally someone points out that the barcode is fine and the Camera app simply does not do product codes, which is correct, and then the thread moves on without anyone explaining why.
It is worth explaining, because the received summary of this whole area — iOS is consistent, Android is fragmented — is not just incomplete for barcodes. For barcodes it is closer to backwards. iOS supports more symbologies at the framework level than Android does, and fewer in the app that ships on the home screen. Both halves of that are checkable, and this article checks them.
The Short Answer
- "Can my phone scan this?" is three separate questions: the Camera app, the platform framework, and the app doing the scanning.
- The iPhone Camera app acts on QR codes only. A UPC, an EAN-13 or a Code 128 produces no result, and that is a limit of the app rather than of the hardware.
- Underneath it, iOS declares nineteen barcode symbologies that any app may request — thirteen since iOS 7 and 8, and six more added in iOS 15.4.
- Android’s ML Kit documents thirteen. It has no GS1 DataBar, no Micro QR and no Micro PDF417, and it reports an ITF-14 as ordinary ITF.
- So the same GS1 DataBar coupon can scan on an iPhone and fail on an Android phone for reasons that have nothing to do with print quality.
- On Android the built-in camera generally only auto-detects QR codes too, but Google Lens does read product barcodes — which gives Android a built-in route to a UPC that iOS does not have.
- MaxiCode, the code on UPS parcels, is in neither platform’s list. No general-purpose phone scanner will decode it.
- iOS has no UPC-A symbology at all. A UPC-A comes back through the EAN-13 type as thirteen digits with a leading zero.
Three questions wearing one coat
Almost every confused thread about phone barcode scanning comes from collapsing three different questions into one. They have different answers, and knowing which one you are actually asking tells you whether the fix is a setting, an app, or an upgrade.
| Layer | What it decides | What you can do about it |
|---|---|---|
| The Camera app | Which codes get a tap-through prompt with no extra software installed. | Nothing. It is a fixed product decision. |
| The platform framework | The ceiling. Which symbologies any app on that OS version can ask for at all. | Update the OS, or accept the ceiling. |
| The app you installed | Which of those symbologies it actually requests. | Install one that requests the format you need. |
"My phone cannot scan barcodes" is nearly always a statement about the first row being mistaken for the second. The phone can. The app on the home screen will not.
What the iPhone Camera app actually does
Since iOS 11 the Camera app has detected QR codes in the live preview and offered to act on them, and the Code Scanner control in Control Centre does the same thing in a dedicated interface. Both stop at QR codes. Point either at a retail barcode and you get silence — not an error, not a "format not supported" message, just nothing, which is exactly why people conclude the barcode must be damaged.
This is a deliberate scope decision and not a capability gap. The frameworks beneath the Camera app have decoded retail barcodes since 2013. The Camera app just does not ask them to, presumably because a phone that threw up a prompt every time a shopping bag drifted through the viewfinder would be unbearable. The practical consequence is that on iOS, reading a product barcode requires a third-party app. There is no built-in path.
What iOS supports underneath: nineteen symbologies
The authoritative list is not a vendor page — it is the AVFoundation SDK header, where each symbology is declared as an AVMetadataObjectType constant carrying an availability annotation that states the iOS version it arrived in. Reading the header rather than a blog post gives both the complete set and the version cut-offs.
Thirteen symbologies have been there since the early days:
| Symbology | Constant | Since |
|---|---|---|
| QR Code | AVMetadataObjectTypeQRCode | iOS 7.0 |
| Aztec | AVMetadataObjectTypeAztecCode | iOS 7.0 |
| PDF417 | AVMetadataObjectTypePDF417Code | iOS 7.0 |
| EAN-13 | AVMetadataObjectTypeEAN13Code | iOS 7.0 |
| EAN-8 | AVMetadataObjectTypeEAN8Code | iOS 7.0 |
| UPC-E | AVMetadataObjectTypeUPCECode | iOS 7.0 |
| Code 39 | AVMetadataObjectTypeCode39Code | iOS 7.0 |
| Code 39 mod 43 | AVMetadataObjectTypeCode39Mod43Code | iOS 7.0 |
| Code 93 | AVMetadataObjectTypeCode93Code | iOS 7.0 |
| Code 128 | AVMetadataObjectTypeCode128Code | iOS 7.0 |
| Data Matrix | AVMetadataObjectTypeDataMatrixCode | iOS 8.0 |
| Interleaved 2 of 5 | AVMetadataObjectTypeInterleaved2of5Code | iOS 8.0 |
| ITF-14 | AVMetadataObjectTypeITF14Code | iOS 8.0 |
Six more were added in iOS 15.4, and this is the release that quietly changed what is possible on a phone:
| Symbology | Constant | Why it matters |
|---|---|---|
| Codabar | AVMetadataObjectTypeCodabarCode | Blood banks, libraries, photo labs. |
| GS1 DataBar | AVMetadataObjectTypeGS1DataBarCode | Loose produce and coupons. |
| GS1 DataBar Limited | AVMetadataObjectTypeGS1DataBarLimitedCode | Very small healthcare packs. |
| GS1 DataBar Expanded | AVMetadataObjectTypeGS1DataBarExpandedCode | Variable-measure grocery, weight and expiry data. |
| Micro QR | AVMetadataObjectTypeMicroQRCode | Tiny parts and electronics. |
| Micro PDF417 | AVMetadataObjectTypeMicroPDF417Code | Small healthcare and electronics labels. |
Nineteen in total. And one absence in that list is more interesting than any of the additions.
iOS has no UPC-A
There is no AVMetadataObjectTypeUPCACode. There never has been. A twelve-digit UPC-A, the standard barcode on every product sold in the United States, is not a symbology iOS names.
What happens instead is that a UPC-A arrives through the EAN-13 type, as thirteen digits with a leading zero on the front. This is not a bug and it is not a workaround: a UPC-A genuinely is an EAN-13 whose first digit is zero, because GS1 defines UPC-A and EAN-13 as two lengths of the same identifier rather than two numbering systems. The bars are identical. The only difference is how many digits get printed underneath.
It catches developers out constantly, though, because code that asks "did I scan a UPC?" by comparing the reported symbology never matches on iOS. The correct test is on the digits, not the type — and a twelve-digit UPC-A and its thirteen-digit form both resolve to the same product. If you have a number and want to see every equivalent form of it, the GTIN converter does that conversion and recomputes the check digit for each length.
What Android supports: thirteen formats
Most Android barcode scanning, including this app’s, runs on Google’s ML Kit. Google documents thirteen supported formats: QR Code, Aztec, PDF417, Data Matrix, EAN-13, EAN-8, UPC-A, UPC-E, Codabar, Code 39, Code 93, Code 128 and ITF.
Line that up against the iOS list and the gaps fall out:
| Format | iOS | Android ML Kit |
|---|---|---|
| GS1 DataBar | iOS 15.4 | Not supported |
| GS1 DataBar Limited | iOS 15.4 | Not supported |
| GS1 DataBar Expanded | iOS 15.4 | Not supported |
| Micro QR | iOS 15.4 | Not supported |
| Micro PDF417 | iOS 15.4 | Not supported |
| ITF-14 | Distinct type since iOS 8.0 | Reported as plain ITF |
| Code 39 mod 43 | Distinct type since iOS 7.0 | Reported as Code 39 |
| UPC-A | No type — arrives as EAN-13 | Distinct type |
| MaxiCode | Not supported | Not supported |
So the honest version of the platform comparison is: iOS reaches further into the industrial and GS1 symbologies; Android names UPC-A properly and iOS does not. Everything else in common use — QR, Aztec, PDF417, Data Matrix, the EAN and UPC family, Code 39, Code 93, Code 128, Codabar, ITF — works on both.
ML Kit also documents some narrower limits that are easy to trip over: no UPC and EAN extension bars, no MaxiCode, and no ITF symbol shorter than six digits. If you are encoding a very short numeric string in ITF and it will not read on Android, that last one is probably why.
The DataBar gap is the one that bites in real life
Of all those differences, GS1 DataBar is the one most likely to cause a genuine argument, because it turns up on things ordinary shoppers scan: loose fruit and vegetables, money-off coupons, small pharmacy packs. An iPhone on iOS 15.4 or later can read it. An Android phone, running a scanner built on ML Kit, cannot.
Two people standing in the same aisle will therefore get different results from the same label, and neither of them has done anything wrong. If you hit this, the format is the explanation, not the lighting. GS1 DataBar Expanded carries application identifiers in the same style as GS1-128 and GS1 DataMatrix, and if you can get the data off it by any means the GS1 barcode decoder will break the element string apart for you.
The failure mode nobody writes about
There is a third-layer problem that is invisible from outside and worth knowing if you are building anything that scans.
On iOS, the list of symbologies a device offers is not the same as the list the SDK declares. It is exposed per device as availableMetadataObjectTypes, and an older handset that predates the iOS 15.4 decoders will not offer Codabar or the GS1 DataBar family however new its software is. The trap is what happens when an app asks anyway: the metadata output rejects the whole configuration rather than ignoring the one type it cannot provide. Ask for fourteen symbologies on a device that supports thirteen of them and you get zero, not thirteen.
We hit exactly this. The comment sitting in our own scanner today records the fix:
Minimal
codeTypesused as a last-resort fallback when iOS rejects the configured set (AVCaptureMetadataOutputthrowscode-scanner/code-type-not-supportedfor the entire config if any one requested type isn’t in the device’savailableMetadataObjectTypes— e.g. an older device that lacks the iOS 15.4 codabar/GS1-DataBar decoders).
The practical upshot for a user is a scanner that works on a new phone and appears completely dead on an old one, with no error anywhere. If a scanning app is fine for everyone except the person with the older handset, this is the first thing to suspect, and it has nothing to do with the barcode.
Android’s built-in route: Google Lens, not the camera
The Android side is genuinely more varied, but not in the direction the usual summary implies. Most Android camera apps, like Apple’s, auto-detect QR codes and leave product barcodes alone. What Android has that iOS does not is Google Lens, which is bundled on most modern Android phones and does read retail barcodes, returning shopping results for a UPC or EAN.
So for the specific task of pointing a phone at a tin of beans and getting something useful, Android has a built-in answer and iOS does not. That is the opposite of the way the platform comparison is usually told, and it comes about because the fragmentation everyone cites is fragmentation of the camera app, while the thing that matters for barcodes is what the decoding layer underneath supports.
Lens is not a general-purpose scanner, though. It is oriented towards lookups rather than giving you the raw data, and it is not the place to go if you need the element string out of a GS1-128 or the fields out of a driving licence PDF417.
What you will actually meet, and what reads it
Stripped of the platform detail, here is the practical version for the codes most people encounter.
| Where you see it | Usually | Reads on a phone? |
|---|---|---|
| Menu, poster, ticket link | QR Code | Yes, including the built-in camera on both platforms. |
| Supermarket product | EAN-13 or UPC-A | Yes, but not from the iPhone Camera app. Needs a scanner app, or Lens on Android. |
| Small pack, cosmetics | EAN-8 or UPC-E | Yes, with a scanner app. UPC-E needs expanding before a lookup will find it. |
| Parcel and courier labels | Code 128, often GS1-128 | Yes, with a scanner app, on both platforms. |
| Outer shipping carton | ITF-14 | Yes. iOS names it as ITF-14; Android returns the digits as plain ITF. |
| Boarding pass | Aztec or PDF417 | Yes, with a scanner app, on both platforms. |
| Driving licence, ID card | PDF417 | Yes, with a scanner app, on both platforms. |
| Medicine pack, medical device | GS1 DataMatrix | Yes, with a scanner app, on both platforms. |
| Loose produce, coupons | GS1 DataBar | iPhone on 15.4 or later only. Android ML Kit cannot. |
| UPS parcel | MaxiCode | No. Neither platform supports it. |
If you are trying to work out which of these you are holding, the barcode format identifier takes a description of the symbol — its shape, its finder pattern, how many digits it prints — and ranks the candidates, with the platform support for each. For the wider taxonomy of what each format is for, rather than what reads it, there is types of barcodes explained.
How to tell the formats apart by eye
For 2D codes the finder pattern settles it almost every time, and it is the fastest thing to look for.
- Three solid squares in three corners — QR Code.
- One solid square in a single corner — Micro QR. Worth spotting, because Android will not read it.
- Two solid edges forming an L, with the opposite edges alternating black and white — Data Matrix.
- Concentric squares in the middle — Aztec.
- Hexagonal cells around a round bullseye — MaxiCode. Nothing on your phone will read it.
- Stacked rows of short bars, much wider than tall — PDF417.
PDF417 is the interesting one, because it has no internal marker at all. It is bounded left and right by start and stop bar patterns instead, and in the reference ZXing implementation those are the fixed sequences {8, 1, 1, 1, 1, 1, 1, 3} and {7, 1, 1, 3, 1, 1, 1, 2, 1}. The first element of the start pattern is a bar eight modules wide, which is why the leftmost thing you can see on a PDF417 is a noticeably thick black line.
For 1D codes, count the printed digits. Thirteen is EAN-13, twelve is UPC-A, fourteen inside a heavy black frame is ITF-14. Eight is genuinely ambiguous — both EAN-8 and UPC-E print eight digits, and you cannot tell them apart by looking. Anything with letters in it rules the retail codes out entirely and leaves Code 128, Code 39 or Code 93. If the printed line starts and ends with a letter A to D, it is Codabar.
Frequently Asked Questions
Why will my iPhone not scan a barcode?
Because the Camera app only acts on QR codes, and it fails silently on everything else. This is a scope limit of the app, not of the phone: AVFoundation has decoded EAN-13, UPC-E, Code 128, PDF417 and Data Matrix since iOS 7 and 8, and any third-party scanner can request them. There is no setting that will make the Camera app read a product barcode, so a separate app is the only route on iOS.
How many barcode formats can an iPhone read?
Nineteen, at the framework level, as declared in the AVFoundation SDK headers. Thirteen date from iOS 7.0 and 8.0 and six were added in iOS 15.4: Codabar, GS1 DataBar, GS1 DataBar Limited, GS1 DataBar Expanded, Micro QR and Micro PDF417. Whether a particular app reads all nineteen depends on which ones it asks for, and whether a particular device offers all nineteen depends on its age and iOS version.
Can Android scan the same barcodes as an iPhone?
Mostly, with a handful of real exceptions. Google’s ML Kit documents thirteen formats and covers everything in common use, but it has no GS1 DataBar, no Micro QR and no Micro PDF417, and it reports an ITF-14 as plain ITF rather than as a distinct format. In the other direction, Android names UPC-A as its own format while iOS has no UPC-A type at all.
Why does a barcode scan on my friend’s phone and not mine?
Three likely reasons, in order. The app you are using may not have requested that symbology. The platform may not support it, which is the story with GS1 DataBar on Android. Or your device may be too old for it: the six symbologies added in iOS 15.4 are unavailable on earlier releases, and on iOS an app that requests a type the device does not offer can have its entire configuration rejected rather than just that one type ignored.
Is there a barcode that no phone can read?
MaxiCode is the everyday example. It is the code on UPS parcel labels, with hexagonal cells around a circular bullseye, and it appears in neither the AVFoundation symbology list nor ML Kit’s documented formats. A general-purpose phone scanner will not decode it. Dedicated logistics hardware will, which is why you see it scanned constantly in depots and never on a phone.
Why does my UPC come back as thirteen digits?
Because iOS has no UPC-A symbology, so a UPC-A is reported through the EAN-13 type with a leading zero added. That is genuinely what a UPC-A is — GS1 treats UPC-A and EAN-13 as two lengths of one identifier, and the printed bars are identical. Strip the leading zero and you have the twelve digits you expected; the check digit is the same either way, because no digit moves relative to it.
Does Google Lens count as a barcode scanner?
For looking a product up, yes, and it is a genuine advantage Android has over iOS, which offers no built-in way to read a retail barcode at all. But Lens is built around answering "what is this product" rather than handing you the data. If you need the raw digits, the application identifiers out of a GS1-128, or the fields from a PDF417 on an ID card, it is not the right tool.
Can my phone scan a barcode from a screen or a photo?
Usually, and the format rules above still apply — a 1D barcode read from an image is subject to the same symbology support as one read off a pack. Two extra things go wrong with screens specifically: a dimmed display gives a scanner almost no contrast, and a dark-mode app that renders the code white-on-black inverts the polarity, which many 1D scanners reject outright even when the contrast is perfect.
The Short Version
Three layers, three answers. The Camera app on an iPhone reads QR codes and nothing else, silently. The iOS framework beneath it declares nineteen symbologies, thirteen of them for over a decade and six since iOS 15.4. Android’s ML Kit documents thirteen, missing the GS1 DataBar family, Micro QR and Micro PDF417, and naming UPC-A where iOS does not.
Which means the familiar line about iOS being consistent and Android being fragmented describes camera apps, not barcodes. On the thing that decides whether a symbol decodes at all, iOS reaches further, and the gap between the two platforms is small but real and lands on things people genuinely scan — loose produce, coupons, small pharmacy packs.
The single most useful takeaway is the simplest: if a barcode will not scan on your phone, check what format it is before you blame the label. Half the time the answer is that nothing was ever going to read it with the app you were using.