JWS vs JWE: Why some JWTs can be read and others cannot
Understand the difference between signed and encrypted JOSE objects so you know when decode is possible and when it is not.

Tip
Decode a small sample first and confirm whether you are changing representation, changing structure, or actually protecting content.
Developers often say “JWT” when they mean one of two different JOSE objects. That shorthand is harmless until someone pastes a five-part token into a decoder and expects the payload to appear.
The practical split is simple: signed tokens can usually be decoded without the key, but encrypted tokens cannot. Verification and decryption are different jobs.
Summary
Definition: JWS protects integrity and authenticity with a signature or MAC, while JWE protects confidentiality by encrypting content.
Why it matters: If you misidentify the object, you will reach for the wrong tool and misread normal behavior as a failure.
Pitfall: Decoding a JWS is not the same as verifying it, and not being able to read a JWE payload is expected.
Count the segments first
Compact JWS commonly appears as three Base64URL segments: header, payload, signature. Compact JWE commonly appears as five: protected header, encrypted key, IV, ciphertext, authentication tag. If you count first, you avoid a surprising number of wrong turns.
This is a good example of pyramid-principle debugging. Start with the highest-level distinction that splits the problem in two. Only after you know whether the object is signed or encrypted does it make sense to talk about keys, claims, or algorithms.
What you can inspect without the key
With JWS, the header and payload are Base64URL encoded, not secret by default. You can inspect them. You still have to verify the signature separately. With JWE, only the protected header is directly visible. The payload stays encrypted until the correct decryption path is available.
That difference matters operationally. A decode tool should never imply that an encrypted payload is “broken” because it stays unreadable. Readability is the wrong expectation in the first place.
- JWS: inspectable structure, verification still required.
- JWE: visible header, unreadable payload until decryption.
- JWT is a family label in conversation, not a promise that the object is readable.
Where real incidents go sideways
The common mistake is to treat a signed token like proof of secrecy. It is not. Anyone who can see the token can decode its payload unless the application uses JWE. The second mistake is the reverse: assuming a five-part token is malformed because a payload viewer cannot show it.
The better workflow is to label the object, inspect only what is supposed to be inspectable, and then move to the matching operation: verify for JWS, decrypt for JWE.
Quick example
Use this when a token decoder shows a header but not a payload and you are not sure whether that is expected.
What to notice: The segment count is not the whole story, but it is the fastest first sort. Three segments usually means signed content. Five usually means encrypted content.
JWS compact: header.payload.signature
JWE compact: protectedHeader.encryptedKey.iv.ciphertext.tag
Practical check
- Count segments before trying to decode claims.
- If the object has five parts, stop expecting the payload to be readable without a key.
- Do not treat base64 readability as proof of trust.
FAQ
Can a JWS still contain sensitive information?
Yes. Signed does not mean encrypted, so sensitive claims should be treated carefully.
Can I verify a JWE the same way I verify a JWS?
No. JWE is about decryption and authentication of encrypted content, not a detached signature workflow.
Developer workflow
Use this guide as a representation check before you move bytes between an API, token, URL, or file format.
- Encode or decode a small sample first, not the production payload.
- Confirm whether the step changes only representation or changes the underlying structure.
- Keep the original and transformed values together until the receiving system accepts the result.
1. raw bytes or text
2. encode/decode for transport
3. decode back to confirm round trip
4. send only after structure still matches