Contributor
Contributor

vRO REST request failing with 406 error

I am recieving a 406 error when executing a GET against the vRA 8 REST API.

When executing in POSTman I get a response in JSON and I have set the default content type.

I am passing the bearer token in the headers string array variable and it seems to be accepted.

The 406 error suggests a not acceptable from the sever - what format should the header be in with the bearer token?

0 Kudos
10 Replies
VMware Employee
VMware Employee

Please provide more info - which REST API are you calling, what is the HTTP method, what headers (and their values) are populated in the request, what's the request body (if any), etc.

Error 406 indicates that the server cannot produce a response matching the acceptable formats specified in the request. For example, the particular REST API you are calling can return objects in JSON format but your request has a header like Accept: text/html, which cannot be satisfied by the JSON response payload.

0 Kudos
Contributor
Contributor

The rest api is the deployments vRA 8 api

GET

https://vRA-FQDN/deployment/api/deployments/ad9b8f26-a8bc-4a09-b1e0-9702d53e12a0?expandResources=tru...'

Headers

Content-Type  application/json - this is being passed as part of the defaultContentType in the operation

"Authorization: Bearer XXX"

0 Kudos
Contributor
Contributor

It feels more to do with the format of the headers as I get the same error when I make changes to the acceptHeaders array string formats.
0 Kudos
VMware Employee
VMware Employee

  • apiVersion=api_version='2019-09-12' query parameter seems wrong to me. I think it should be something like apiVersion=2019-09-12
  • As this is a GET request, you don't need to use Content-Type header
  • You haven't specified Accept header value. Depending on the HTTP/REST client you are using, it may default to various things. Please provide Accept header explicitly with value application/json
0 Kudos
Contributor
Contributor

Here is the response from the failed job in the logs 

2020-03-10 13:36:39.000 -04:00INFO__item_stack:/item0
2020-03-10 13:36:39.000 -04:00INFO
2020-03-10 13:36:39.000 -04:00INFO acceptHeaders Authorization: Bearer XXX,Content-Type: application/json
2020-03-10 13:36:39.000 -04:00INFORequest: DynamicWrapper (Instance) : [RESTRequest]-[class com.vmware.o11n.plugin.rest.Request] -- VALUE : com.vmware.o11n.plugin.rest.Request@7274992c
2020-03-10 13:36:39.000 -04:00INFOResponse: DynamicWrapper (Instance) : [RESTResponse]-[class com.vmware.o11n.plugin.rest.Response] -- VALUE : com.vmware.o11n.plugin.rest.Response@419acdbd
2020-03-10 13:36:39.000 -04:00INFOStatus code: 406
2020-03-10 13:36:39.000 -04:00INFOContent as string:
2020-03-10 13:36:39.000 -04:00INFO****Headers****
2020-03-10 13:36:39.000 -04:00INFOTue, 10 Mar 2020 17:36:39 GMT
2020-03-10 13:36:39.000 -04:00INFOno-cache
2020-03-10 13:36:39.000 -04:00INFODENY
2020-03-10 13:36:39.000 -04:00INFOnosniff
2020-03-10 13:36:39.000 -04:00INFOno-cache, no-store, max-age=0, must-revalidate
2020-03-10 13:36:39.000 -04:00INFO1; mode=block
2020-03-10 13:36:39.000 -04:00INFO0
2020-03-10 13:36:39.000 -04:00INFO0
2020-03-10 13:36:39.000 -04:00INFO__item_stack:/item3
2020-03-10 13:36:39.000 -04:00ERRORError in (Workflow:Invoke a REST operation / Check status code (item3)#1) HTTPError: status code: 406
2020-03-10 13:36:39.000 -04:00ERRORWorkflow execution stack: *** item: 'Invoke a REST operation/item3', state: 'failed', business state: 'null', exception: 'HTTPError: status code: 406 (Workflow:Invoke a REST operation / Check status code (item3)#1)' workflow: 'Invoke a REST operation' (A18080808080808080808080808080808080808001299080088268176866967b3) | 'attribute': name=errorCode type=string value= | 'attribute': name=statusCodeAttribute type=number value=406.0 | 'input': name=restOperation type=REST:RESTOperation value=dunes://service.dunes.ch/CustomSDKObject?id='609a387b-1ab6-4a92-ba4e-328a7d3ae1a2:251da4a3-b62d-4cc9-9799-54218895e107'&dunesName='REST:RESTOperation' | 'input': name=param_0 type=string value=ad9b8f26-a8bc-4a09-b1e0-9702d53e12a0 | 'input': name=param_1 type=string value=<> | 'input': name=param_2 type=string value=<> | 'input': name=param_3 type=string value=<> | 'input': name=param_4 type=string value=<> | 'input': name=param_5 type=string value=<> | 'input': name=param_6 type=string value=<> | 'input': name=param_7 type=string value=<> | 'input': name=param_8 type=string value=<> | 'input': name=param_9 type=string value=<> | 'input': name=param_10 type=string value=<> | 'input': name=param_11 type=string value=<> | 'input': name=param_12 type=string value=<> | 'input': name=param_13 type=string value=<> | 'input': name=param_14 type=string value=<> | 'input': name=content type=string value= | 'input': name=defaultContentType type=string value=application/json | 'input': name=headerParam_0 type=string value=<> | 'input': name=headerParam_1 type=string value=<> | 'input': name=headerParam_2 type=string value=<> | 'input': name=headerParam_3 type=string value=<> | 'input': name=headerParam_4 type=string value=<> | 'input': name=headerParam_5 type=string value=<> | 'input': name=acceptHeaders type=Array/string value=#{#string#Authorization: Bearer XXXX#;#string#Content-Type: application/json#}# | 'output': name=statusCode type=number value=406.0 | 'output': name=contentLength type=number value=0.0 | 'output': name=headers type=Properties value=#[#X-Frame-Options#=#string#DENY#+#Cache-Control#=#string#no-cache, no-store, max-age=0, must-revalidate#+#X-Content-Type-Options#=#string#nosniff#+#X-Xss-Protection#=#string#1; mode=block#+#Pragma#=#string#no-cache#+#Expires#=#string#0#+#Content-Length#=#string#0#+#Date#=#string#Tue, 10 Mar 2020 17:36:39 GMT#]# | 'output': name=contentAsString type=string value= *** End of execution stack.
0 Kudos
VMware Employee
VMware Employee

2020-03-10 13:36:39.000 -04:00INFO acceptHeaders Authorization: Bearer XXX,Content-Type: application/json

The above is totally wrong.

'Invoke a REST Operation' workflow's second input parameter is labelled 'Accept Headers'. Not 'Authorization', not 'Content-Type'. So please remove what you've set there and provide just the string application/json.

0 Kudos
VMware Employee
VMware Employee

BTW, I tested this workflow with some REST operations that are able to return either JSON or XML responses, and when I provided the values from your run, it indeed failed (although with a slightly different error).

I guess a part of the problem is that semantically the input parameter 'Accept Headers' can be interpreted in two ways, either

  • as a list of header names and values that the HTTP request call takes (as in your case, Authorization and Content-Type headers with their values), or
  • as a list of header values (without header names) that are the MIME types to be passed to the HTTP request as values for 'Accept' HTTP header

The latter if what the stock workflow 'Invoke a REST operation' expects; you can check the scripting code in this workflow to see how the value of input parameter acceptHeaders is processed.

0 Kudos
Contributor
Contributor

Hey Ilian,

Thanks for responding, I have tried many different formats and I do see that the header for Authorization is being read and I suspect I am not providing it in the way the rest invoke operation workflow expects.

You mentioned looking at the code for the workflow, in previous versions you could look at the script tab, that isn't there in vRO 8 for the invoke rest operation. Can you point me to how I can view the code?

0 Kudos
Contributor
Contributor

Ignore last post - I found it

0 Kudos
Contributor
Contributor

Hey Ilian,

I have managed to figure this out.

I ended up cloning the Invoke REST Operation workflow.

In the code there is no place to add an Authorization Header.

I ended up adding an input variable 'token' and then added the line "request.setHeader('Authorization','Bearer ' + token);"

This now operates the way I would expect.

As a side note the acceptHeaders variable is pre-pended with the string "accept" for all strings in the array.

I found I didn't need this variable at all and setting the defaultContentType variable to application/json was good enough.

Thanks,

Daniel

0 Kudos