Pick up any modern Android phone, run adb shell getprop ro.build.fingerprint, and
you'll get back a long, slash-separated string like this:
samsung/dm3qxxx/dm3q:14/UP1A.231005.007/S911BXXS5BXG2:user/release-keys
That's the canonical "fingerprint" of an Android build. It's set at the factory, baked into the system partition, and read by everything from your bank app to the Play Store to ad networks. Understanding it is the foundation of every "is this phone real?" check.
The 6-field structure
Per the AOSP source, Build.FINGERPRINT is always:
$<brand>/<product>/<device>:<release>/<id>/<incremental>:<type>/<tags>
That's 6 fields separated by /, with a stray : inside fields 3 and 5.
Each one is set independently and tells you a different thing.
Field 1: brand
This is what ro.product.brand resolves to. For a real Samsung Galaxy, it's
always lowercase samsung. Capitalization mismatches are the
single most reliable counterfeit signal — clone shops routinely set it to Samsung,
SAMSUNG, or worse, SAMUNG.
Look up the expected brand string for any verified device in our brand database.
Field 2: product
The internal product codename. dm3qxxx in the example is Samsung's internal
codename for the Galaxy S23. Each variant has its own product code: dm1qxxx for
S23, dm2qxxx for S23+, dm3qxxx for S23 Ultra. Regional variants
also vary — dm3qins for India, dm3qxxx for international.
This is hard to fake because the codename has to match the kernel device tree binding. If you flash a S23 ROM onto an S22 board, the product field will fight the actual hardware and cause crashes during early boot.
Field 3: device:release
Two fields joined by a colon. dm3q:14 means device codename dm3q
running Android 14.
The device codename is often a shortened version of the product codename — it identifies the hardware platform that the kernel was built for. The release version is the user-facing Android version number.
Mismatches here are diagnostic. A device codename of generic means emulator. A
release version that doesn't match an officially shipped Android version on that hardware
means custom ROM.
Field 4: id
The internal build ID, set by the OEM's build system. Samsung uses
UP1A.231005.007 style — UP for "Upside-down cake" (Android 14 codename), 1A for
platform release, 231005 is the build date (2023-10-05), 007 is the incremental number.
Pixel devices use a similar but different convention: AP2A.240605.005 for
Android 14, where AP stands for "Android Pixel."
The build ID is the single best field for "is this firmware up to date?" — compare it against the latest official release for the model.
Field 5: incremental:type
Two fields joined by a colon. S911BXXS5BXG2:user is:
S911BXXS5BXG2— Samsung's incremental version string.S911Bis the model number prefix.XXis region.S5is firmware revision.BXG2is build date encoded.user— the build type. Almost alwaysuseron production phones. If you seeuserdebugoreng, it's a development device or a custom ROM.
Field 6: tags
Build tags, almost always release-keys on production devices. The other value
you'll see is test-keys, which means the build was signed by AOSP test keys
rather than the OEM's release keys.
This is the most useful single field for detecting custom ROMs. If
Build.FINGERPRINT ends in test-keys, the phone is either rooted, on a custom
ROM, or both. Many banking apps refuse to run on test-keys builds.
What's safe to parse, what isn't
Build.FINGERPRINT is set in the system partition and read by the framework. Apps can read it but cannot change it. Almost.
Magisk (the most popular root manager) supports a "MagiskHide / DenyList" feature that hooks the property read and serves a different fingerprint to selected apps. So a rooted phone may show one fingerprint to Settings and a different one to your bank app. This is why bank apps don't rely on fingerprint alone — they pair it with SafetyNet attestation, Play Integrity API, and hardware-backed key attestation.
For your own purposes (checking a second-hand phone before you buy), Build.FINGERPRINT is still extremely useful. The seller can't pre-hook it without you knowing. And anomalies in the structure are easy to spot once you know what each field encodes.
The 30-second sanity check
Pull Build.FINGERPRINT and walk through:
- Brand lowercase? ✓
- Product codename matches the claimed model? Cross-reference our device database.
- Device codename plausible for the hardware? ✓
- Release version matches a shipped Android version on this model? ✓
- Build ID structure matches the OEM's known format? ✓
- Build type is
user, notuserdebug? ✓ - Tags is
release-keys, nottest-keys? ✓
Seven boxes. If any of them fail, the phone has been modified — and you need to know how before you pay.