specdeviceinfo
2026-06-05 · Technical explainer

Reading Build.FINGERPRINT: what each field actually means

The Android Build.FINGERPRINT string looks like noise. It isn't — every character is doing something. Here's a field-by-field tour, and what each segment tells you about the device.

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. S911B is the model number prefix. XX is region. S5 is firmware revision. BXG2 is build date encoded.
  • user — the build type. Almost always user on production phones. If you see userdebug or eng, 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:

  1. Brand lowercase? ✓
  2. Product codename matches the claimed model? Cross-reference our device database.
  3. Device codename plausible for the hardware? ✓
  4. Release version matches a shipped Android version on this model? ✓
  5. Build ID structure matches the OEM's known format? ✓
  6. Build type is user, not userdebug? ✓
  7. Tags is release-keys, not test-keys? ✓

Seven boxes. If any of them fail, the phone has been modified — and you need to know how before you pay.