preferred_username Claim in an ID Token
preferred_username is the shorthand name the end user wants to be referred to by. OpenID Connect states plainly that it is neither guaranteed unique nor guaranteed stable, so it belongs in the interface and nowhere else.
At a glance
- Claim
- preferred_username
- Defined in
- OpenID Connect Core 1.0 section 5.1
- Value type
- String, chosen by the end user or assigned by the provider
- Required
- Optional. Returned with the profile scope when the provider supports it.
- Sample value
- jreyes
- In the decoder
- Shown under Custom claims with its raw value, next to the other profile claims the issuer released.
In detail
OpenID Connect says the value must not be relied upon to be unique and that relying parties must not treat it as such. Providers vary wildly in what they put here: a short handle, a full email address, a directory account name, sometimes the same value the person could change five minutes later from their profile page. Nothing in the specification stops any of that.
The practical rule is that it is a display value. Show it in a greeting, in an avatar tooltip, in an audit line next to the real subject identifier. Do not key records on it, do not use it in a permission check, and do not use it to look an account up, because two people can carry the same value and one person can carry two over time.
It also arrives from outside your system, which makes it untrusted input. A value can contain markup, control characters, right to left overrides or homoglyphs picked to resemble another user's name, so escape it wherever it is rendered and normalize it before any comparison. Treating it with the same suspicion as a form field is the correct posture.
Its presence depends on the profile scope being granted and on the provider supporting the claim at all, so plan for it being absent. The decoder lists it under Custom claims with the value exactly as it was encoded, which is the fastest way to see what a given provider actually puts there before you decide how to display it.
Examples
// Provider A
{ "sub": "8f14e45fceea167a5a36dedd4bea2543", "preferred_username": "jreyes" }
// Provider B
{ "sub": "Xk9d2mQ7pR4tLb1sVc8n", "preferred_username": "jordan.reyes@example.com" }Both are valid. Only sub, read together with iss, identifies the account in either case.
Things that catch people out
- Using it as a login identifier or a database key. It is explicitly not guaranteed unique or stable.
- Rendering it without escaping. It is user controlled text that arrives from another system.
- Assuming it is always present. It needs the profile scope, and some providers do not emit it at all.
Try it: JWT Decoder
Paste a token to decode the header and payload, read the claims and expiry, and verify the signature in your browser. Nothing is uploaded.
JWT Decoder
LOCAL · Browser-OnlyDecode and inspect JSON Web Tokens without sending them to a server
Related JWT claims and algorithms
All jwt claims and algorithms →email Claim in an OpenID Connect ID Token
The email claim carries the end user's email address. Why it must not be used as an account key, what scope returns it, and what the decoder shows.
sub (Subject) Claim in a JWT
The sub claim says who the token is about. Why it is only unique within one issuer, what pairwise subjects change, and how the decoder shows it.
email_verified Claim in an OpenID Connect ID Token
The email_verified claim says whether the provider verified the address. Why account linking depends on it, the string true trap, and decoder behaviour.
HS256: HMAC with SHA-256 in a JWT
HS256 signs a JWT with a shared secret using HMAC and SHA-256. Key sizing, the algorithm confusion attack, and verifying one in your browser.
HS384: HMAC with SHA-384 in a JWT
HS384 signs a JWT with a shared secret using HMAC and SHA-384. How it differs from HS256, why SHA-384 is a truncated SHA-512, and verification support.
HS512: HMAC with SHA-512 in a JWT
HS512 signs a JWT with a shared secret using HMAC and SHA-512. Secret sizing, the token size cost, and how the decoder verifies one in your browser.
Tools for this
- JWT Decoder Free online JWT decoder - decode and inspect JSON Web Tokens without sending them to a server