UnauthorizedError: jwt malformed in express.js

I’m trying to validate access token on serverside but getting UnauthorizedError: jwt malformed. It seems that access token is too short (only 16 characters long). In tutorials is it much longer. Where am i wrong?


I have the same symptom. The access_token returned from webAuth.parseHash is just 16 chars (then it’s stored to the localStorage and sent to the server as Bearer). but it doesn’t look like a valid jwt.
so the server fails in the checkJwt() validation with ‘UnauthorizedError: jwt malformed’.

I had been following the code examples from https://auth0.com/docs/quickstart/spa/vanillajs


I think I figured out the solution:

in the app.js, call to const webAuth = new auth0.WebAuth({ you need to replace the content of audience. the example documents https://<DOMAIN>/userinfo, but that must be replaced with the API Audience as set up in the APIs configuration.

once I made that change, it suddently works ok, and the access_token contains a valid jwt.


the code snippet provided in the dashboard > Clients > Quickstart as above https://<DOMAIN>/userinfo is wrong! jwt malformed!
Come on! You’re the official guide!
Solution that worked for me as suggested above:
Dashboard > APIs and under your created API, copy paste the string for API Audience
thank you @sthones you’re a life-saver!


hi, got the same problem, followed the react example and used

var jwtCheck = jwt({
    secret: jwks.expressJwtSecret({
        cache: true,
        rateLimit: true,
        jwksRequestsPerMinute: 15,
        jwksUri: "https://[domain].auth0.com/.well-known/jwks.json"
    audience: "https://[identifier domain].com",
    issuer: "https://[domain].auth0.com/",
    algorithms: 'RS256']

on the client side i’m giving the access token which is 32 characters long but every time I get JWT malformed, been at this problem for hours, any ideas?

Ditto. I wish (oh how I wish) I had read this more thoroughly the first time through as this was exactly the fix I needed. Thanks @sthones !!!

Fixed my problem with this tip too. Absolutely ridiculous that the official guides don’t work. I’ve complained about the poor documentation when I first signed up for auth0, I’m at the point where I’m questioning why I’m even using auth0.


same here… I can’t figure out anymore how it works. The identifier used to be in ‘client’ - ‘settings’ - ‘client ID’ (that’s the one I use for audience). Is that still valid? Or not? If not, where can I find the identifier? Thx!

async function checkJwt(accessToken: string) {
    // return true;
    // Inject accessToken in a header to permit express middleware usage.
    const req: any = { headers: { authorization: `Bearer ${accessToken}` } }

    return new Promise((resolve, reject) => {
        const next = (err) => err ? reject(err) : resolve();
            // Dynamically provide a signing key based on the kid in the header and the singing keys provided by the JWKS endpoint.
            secret: jwksRsa.expressJwtSecret({
                cache: true,
                rateLimit: true,
                jwksRequestsPerMinute: 5,
                jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`

            // Validate the audience and the issuer.
            audience: process.env.AUTH0_AUDIENCE,
            issuer: `https://${process.env.AUTH0_DOMAIN}/`,
            algorithms: 'RS256']
        })(req, null, next)


process.env.AUTH0_DOMAIN <- ‘Clients’ - my client - ‘Settings’ - ‘Client ID’
process.env.AUTH0_AUDIENCE <- one of (none works):

  • ‘Clients’ - my client - ‘Settings’ - ‘Client ID’
  • ‘APIs’ - ‘Auth0 Management API’ - ‘Settings’ - ‘Identifier’
  • ‘APIs’ - my custom api - ‘Settings’ - ‘Identifier’

How to make JWT validation work?
(I guess the problem is that the access token is not a JWT?)

did you solve this? I have the same problem, can’t get it to work…

In the end I switched to Okta, just because their react/node examples worked. I’m sure it was probably something simple but I was just so pushed for time I needed a solution and fast.

Now I’ve got a bit of a breather I’ll probably try to roll my own authentication with passport and jwt tokens.

the problem was my JWT token was too short (32 chars vs 250+) so the server-side was trying to convert it into a json format and couldn’t because it was cut off so the server returned with malformed request.

I think there might be something wrong with the JWT access-token examples, id-token seems to work fine though.

Now i’ve got a bit of a breather I’m going to try and roll my own JWT login/signup with passport.

Will post it here when it works.

yeah, pls… I agree that the problem is the access token: it’s not a JWT. The question boils down to: how to verify it?

Am I right that making a call to the /userinfo endpoint would suffice to know that the token is valid and to get some user info (like email etc)? (Instead of validating a JWT, this would validate the access token by just making that call and checking the result.)

i think if you make a call to /userinfo without being verified it should error out saying your connection is invalid, which you could use to verify the token but it’d be undesirable, it’d be better to validate it with the getAccessToken call and using async await with it to make sure that finishes before you request the userinfo:

const accessToken = await this.getAccessToken()

ok, let me explain the use case: a user authenticates against auth0 but authorization happens in-app. When I get a token from auth0, I want the user to send that token to the app, and the app validates the token. How can my own server validate the opaque string access token? (JWT is straight forward, but what with opaque strings?) Can the server just make the call to the /userinfo endpoint (with the access token in the header)? If not, how to validate that opaque string properly?

any update on this, i’m facing the same issue. passing the id token instead of access token works but don’t think that’s the intended behavior

I’m not sure if this helps, but if you look at the “Authorize the user” subsection under the “Implement the SPA” section here, you’ll see that the “audience” in your client side setup should be the value of the API identifier.

I think it’s easy to gloss over that bit if you’ve already got Auth0 working on the client side using, say, one of the SPA tutorials and then go on to implement the API authorization for the server.

Correct Configuration on Express side which is working fine for me

   const authCheck = jwt({
    secret: jwks.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: ‘https://<something>.auth0.com/.well-known/jwks.json’
    audience: ‘https://<something>.auth0.com/api/v2/’,
    algorithms: [‘RS256’]


Issuer is not actually required in the express configuration.

Correct Configuration Working on Angular side

auth0 = new auth0.WebAuth({
    clientID: <Client_ID>',
    domain: '<something>.auth0.com',
    responseType: 'token',
    redirectUri: 'http://localhost:4200/callback',
    scope: 'openid',
    audience: 'https://<something>.auth0.com/api/v2/',
    issuer: 'https://<something>.auth0.com'

When I close the browser and return to the site, the JWT cannot decode. The JWT can decode when it is placed just under the encoding function. I have tried both the jwt-simple node module and the jsonwebtoken node modules, and I come back with the same error krogerfeedback.