It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Atlassian JIRA Rest API returning unauthorized 401 while calling along with JWT

I am developing a JIRA add-on that creates a JIRA issue. I cannot use basic authentication (that is using the admin username and password) for the REST API calls because of functional requirements henceforth, I have to stick with JWT.

I am using the atlassian-jwt module for node.js to generate the JWT token:


var now = moment().utc();

var req = {
    method: 'GET',
    originalUrl: '/rest/api/2/application-properties/advanced-settings'

var token = {
    "iss": 'issuer-val',
    "iat": now.unix(),                      // the time the token is generated
    "exp": now.add(3, 'minutes').unix(),    // token expiry time (recommend 3 minutes after issuing)
    "qsh": jwt.createQueryStringHash(req)   // [Query String Hash](

var secret = 'The shared secret that I receive while installing the add-on';

var token = jwt.encode(token, secret); 


The token that I am receiving above I am using the same to call the REST API. However even a simple GET request like:

returns Unauthorized 401

I have provided the required scopes in the atlassian-connect.json file as well.

"scopes": [
        "read", "write"


I couldn't find any relevant source pertaining to my problem on the internet and have been searching for hours now.

Anyone with experience in developing add-ons for JIRA please guide me.

3 answers

I have the same result with getting projects /rest/api/2/project

I also tried putting header Authentication: JWT .... the result was better, but still inproductive:
JIRA returned empty array of projects

You're not alone. Anyword on what we might be doing wrong? Does 401 means the JWT isn't valid? If so, how can we test we've generated a valid JWT?

I have the same exact problem using Javascript JWT library from atlassian. I am getting a 401 unauthorized. It also says 'qsh' doesn't match.


What did you guys end up doing @Grover  @Borys_Lebeda  @Kaushal Jain 


Can someone from Atlassian help me with what I am doing wrong here?


The request:

The request we sent was:

Method: POST
Headers: {
  "Connection": "keep-alive",
  "content_type": "application/json",
  "authorization": "JWT ${myJWTtoken}",
  "zapiaccesskey": "${my_issuer}",
  "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.6.1 Chrome/73.0.3683.121 Electron/5.0.10 Safari/537.36",
  "accept": "*/*",
  "accept-encoding": "gzip, deflate",
  "content-type": "application/json",
  "content-length": 68
Body: {"name":"8:45:2 11-15-2019","projectId":"myID","versionId":"myID"}


The response we got was:

Status: 401 - Unauthorized
Headers: {
  "content-encoding": "gzip",
  "content-type": "text/plain;charset=utf-8",
  "date": "Fri, 15 Nov 2019 16:45:02 GMT",
  "server": "Apache-Coyote/1.1",
  "vary": "Accept-Encoding",
  "content-length": "164",
  "connection": "keep-alive"
Body: Expecting claim 'qsh' to have value 'dc8e37069edfb14c506ee47e1c4480b52d1058e44e284a2079a305736d249a0b' but instead it has the value '23432a414394e528c3de984cc5a7292081dc8995ca55cd7a97ae57b5da525589'

After some hurdles, I figured it:

The req should be

req = jwt.Request = jwt.fromMethodAndUrl('POST''');

The qsh should be 

"qsh": jwt.createQueryStringHash(reqcycle_urlbase_url)

Suggest an answer

Log in or Sign up to answer

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you