Also available in: Español · Português · Français · العربية
User agent parser
Every field labelled by how much of the real machine it reflects — real, frozen, a floor, ambiguous, or a token naming a browser this one is not.
What is a user agent parser?
Every request your browser makes carries a User-Agent header: one line of text naming the browser, its version and the machine it is running on. A user agent parser takes that line apart and tells you what it says. Analytics dashboards, server logs and download pages all run one.
The problem is that the line stopped being true. Browsers have spent the last few years replacing the specific parts of it with constants — the same value sent from every machine — because a detailed string is an excellent way to recognise an individual across sites. What is left still looks like a description of your computer, and mostly is not one.
So this parser does the usual job and then does the one thing the others do not: every field it extracts is labelled with how much of the real machine it reflects. Real means it came from your computer. Frozen means the browser sends that exact value to everyone. A floor means the truth is that number or higher. Ambiguous means the value is genuine and still does not identify what it names.
How to use it
- Paste a User-Agent string, or use your own. The button fills in what your browser is sending right now. Strings from a server log, an analytics export or a bug report all work the same way.
- Read the label beside each field, not just the value. Every row carries one sentence saying why it is trustworthy or why it is not, so you can tell at a glance which parts of a log line are worth acting on.
- Look at the token list underneath. It shows every browser and engine the string claims to be, and marks the one that is actually true. In a modern Chrome string that is one of five.
Two browsers freeze the same fields for opposite reasons
Chrome reduced its User-Agent deliberately, and the shape it settled on is not a guess: the engine builds the string from a fixed list of platform values. There are eight of them, five for desktop, so for any one Chrome version there are exactly five such strings in the world. The minor, build and patch numbers have been sent as 0.0.0 since Chrome 101. The Android version is the constant 10 and the device model is the single letter K.
Firefox freezes the same Windows line — and its source comment gives an entirely different reason. It hardcodes NT 10.0 so that Microsoft cannot change a compatibility-sensitive value without Firefox agreeing first. That is a compatibility veto, not a privacy measure, and it lands on precisely the value Chrome arrived at from the other direction.
On Android the two genuinely disagree, and this is the part no parser surfaces. Chrome sends Android 10 from every device. Firefox uses 10 as a floor: below 10 it reports 10, and from 10 upwards it reports the real number, because some enterprise sites refuse clients on old versions. So Android 13 in a log line is truthful if Firefox sent it and impossible if Chrome did, and Android 10 means at most 10 from one browser and means nothing at all from the other. The same token, two meanings, and which one applies is not knowable from the token.
The field most likely to be believed is the least informative of all. A Chromebook reports build 14541.0.0 — far too specific to look like a placeholder, and identical on every Chromebook on earth.
Honest limits
This tool cannot recover what the string does not contain. If you paste a modern Chrome User-Agent, no parser anywhere — this one included — can tell you the Windows version, the macOS version, the Android version or the device. Those are not hidden behind a paywall or a smarter regex. They are simply not in the string.
The Windows case is the one worth remembering, because it is where every parser makes the same confident mistake. Windows 11 still identifies itself as NT 10.0, so a parser that prints Windows 10 is naming an operating system it cannot distinguish from the other one. Measured against a widely used parser, every OS version it reports from a frozen Chromium string is a constant: it names Windows 10, Mac OS 10.15.7 and Android 10, and reports a device model of K. It is not wrong in any way it could avoid — it reports what the string says.
A User-Agent is also self-declared and always has been. Anyone can send anything: browsers have extensions to change it, and the parsed result of a fabricated string is a faithful reading of a lie. Treat what comes out of any parser as what the client said, not as what the client is.
The intended replacement, an API that reports the same information in structured pieces, is available in Chromium browsers and nowhere else. Firefox and Safari have both declined to implement it, and the two engines' public standards positions record why. So for a large share of visitors, the frozen string is not a legacy fallback — it is the only thing there is.
Why is it free?
Because it costs nothing to run. The parsing happens in your browser; nothing is uploaded, no server sees the string, and no account is involved.
The rules come from the source of the two engines that write these strings, not from documentation about them, and the tests that check them are committed alongside the tool.