"TypeError: Failed to fetch" for valid response

Hi all,

I’m having exactly the same issue as this reported bug in github: Valid response returning "TypeError: Failed to fetch" · Issue #3403 · swagger-api/swagger-ui · GitHub.

I’m trying to test an api via the Tyk catalogue. The catalogue returns a “TypeError: Failed to fetch” error. If a monitor the network connection I can see that Tyk is succesfully retrieves a http 200 response message.

We are currently using Tyk version 2.3.9.

I have a feeling that this issue is related to the headers that are included in the response message. The headers that are included are:
pragma: no-cache
date: Fri, 10 Nov 2017 10:47:25 GMT
content-encoding: gzip
server: Microsoft-IIS/10.0
vary: Origin, Accept-Encoding
content-type: application/json; charset=utf-8
x-ratelimit-remaining: 0
cache-control: no-cache
x-ratelimit-reset: 1510307280
x-ratelimit-limit: -1
connection: close
content-length: 33
expires: -1

Are you able to reproduce this at your side or do you have some tips which might solve this issue?

The api definition:
{
“api_model”: {},
“api_definition”: {
“id”: “5a0571cfb8763d02c30a4b17”,
“name”: “SteinwegHierarchy”,
“slug”: “SteinwegHierarchy”,
“api_id”: “e31758f71781473160a6f92387a2dd10”,
“org_id”: “58924c7c660450026f755e09”,
“use_keyless”: false,
“use_oauth2”: false,
“use_openid”: false,
“openid_options”: {
“providers”: [],
“segregate_by_client”: false
},
“oauth_meta”: {
“allowed_access_types”: [],
“allowed_authorize_types”: [],
“auth_login_redirect”: “”
},
“auth”: {
“use_param”: true,
“param_name”: “”,
“use_cookie”: false,
“cookie_name”: “”,
“auth_header_name”: “Authorization”
},
“use_basic_auth”: false,
“enable_jwt”: false,
“use_standard_auth”: true,
“enable_coprocess_auth”: false,
“jwt_signing_method”: “”,
“jwt_source”: “”,
“jwt_identity_base_field”: “”,
“jwt_client_base_field”: “”,
“jwt_policy_field_name”: “”,
“notifications”: {
“shared_secret”: “”,
“oauth_on_keychange_url”: “”
},
“enable_signature_checking”: false,
“hmac_allowed_clock_skew”: -1,
“base_identity_provided_by”: “”,
“definition”: {
“location”: “header”,
“key”: “version”
},
“version_data”: {
“not_versioned”: true,
“versions”: {
“v1”: {
“name”: “v1”,
“expires”: “”,
“paths”: {
“ignored”: [],
“white_list”: [],
“black_list”: []
},
“use_extended_paths”: true,
“extended_paths”: {
“white_list”: [
{
“path”: “/getSteinwegHierarchyComboList”,
“method_actions”: {
“GET”: {
“action”: “no_action”,
“code”: 200,
“data”: “”,
“headers”: {}
}
}
},
{
“path”: “/getOperationalParentByGuid”,
“method_actions”: {
“GET”: {
“action”: “no_action”,
“code”: 200,
“data”: “”,
“headers”: {}
}
}
},
{
“path”: “/getSteinwegHierarchyByGuid”,
“method_actions”: {
“GET”: {
“action”: “no_action”,
“code”: 200,
“data”: “”,
“headers”: {}
}
}
},
{
“path”: “/getSteinwegHierarchyByType”,
“method_actions”: {
“GET”: {
“action”: “no_action”,
“code”: 200,
“data”: “”,
“headers”: {}
}
}
},
{
“path”: “/getOperationalChildByGuid”,
“method_actions”: {
“GET”: {
“action”: “no_action”,
“code”: 200,
“data”: “”,
“headers”: {}
}
}
},
{
“path”: “/getLegalParentByGuid”,
“method_actions”: {
“GET”: {
“action”: “no_action”,
“code”: 200,
“data”: “”,
“headers”: {}
}
}
},
{
“path”: “/getLegalChildByGuid”,
“method_actions”: {
“GET”: {
“action”: “no_action”,
“code”: 200,
“data”: “”,
“headers”: {}
}
}
},
{
“path”: “/”,
“method_actions”: {
“GET”: {
“action”: “no_action”,
“code”: 200,
“data”: “”,
“headers”: {}
}
}
}
]
},
“global_headers”: {},
“global_headers_remove”: [],
“global_size_limit”: 0,
“override_target”: “”
}
}
},
“uptime_tests”: {
“check_list”: [],
“config”: {
“expire_utime_after”: 0,
“service_discovery”: {
“use_discovery_service”: false,
“query_endpoint”: “”,
“use_nested_query”: false,
“parent_data_path”: “”,
“data_path”: “”,
“port_data_path”: “”,
“target_path”: “”,
“use_target_list”: false,
“cache_timeout”: 0,
“endpoint_returns_list”: false
},
“recheck_wait”: 0
}
},
“proxy”: {
“preserve_host_header”: false,
“listen_path”: “/SteinwegHierarchy”,
“target_url”: “http://HOSTNAME:80/MDM_Api/rest/SteinwegHierarchy”,
“strip_listen_path”: true,
“enable_load_balancing”: false,
“target_list”: [],
“check_host_against_uptime_tests”: false,
“service_discovery”: {
“use_discovery_service”: false,
“query_endpoint”: “”,
“use_nested_query”: false,
“parent_data_path”: “”,
“data_path”: “”,
“port_data_path”: “”,
“target_path”: “”,
“use_target_list”: false,
“cache_timeout”: 0,
“endpoint_returns_list”: false
}
},
“disable_rate_limit”: false,
“disable_quota”: false,
“custom_middleware”: {
“pre”: [],
“post”: [],
“post_key_auth”: [],
“auth_check”: {
“name”: “”,
“path”: “”,
“require_session”: false
},
“response”: [],
“driver”: “”,
“id_extractor”: {
“extract_from”: “”,
“extract_with”: “”,
“extractor_config”: {}
}
},
“custom_middleware_bundle”: “”,
“cache_options”: {
“cache_timeout”: 0,
“enable_cache”: false,
“cache_all_safe_requests”: false,
“cache_response_codes”: [],
“enable_upstream_cache_control”: false
},
“session_lifetime”: 0,
“active”: true,
“auth_provider”: {
“name”: “”,
“storage_engine”: “”,
“meta”: {}
},
“session_provider”: {
“name”: “”,
“storage_engine”: “”,
“meta”: null
},
“event_handlers”: {
“events”: {}
},
“enable_batch_request_support”: false,
“enable_ip_whitelisting”: false,
“allowed_ips”: [],
“dont_set_quota_on_create”: false,
“expire_analytics_after”: 0,
“response_processors”: [],
“CORS”: {
“enable”: true,
“allowed_origins”: [
"
],
“allowed_methods”: [
“GET”,
“PUT”,
“POST”,
“DELETE”
],
“allowed_headers”: [
"

],
“exposed_headers”: [
“*”
],
“allow_credentials”: false,
“max_age”: 0,
“options_passthrough”: false,
“debug”: false
},
“domain”: “apim-dev.srv.steinweg.nl”,
“do_not_track”: false,
“tags”: [],
“enable_context_vars”: false,
“config_data”: {}
},
“hook_references”: [],
“is_site”: false,
“sort_by”: 0
}

SWAGGER definition of catalogue:
{
“swagger” : “2.0”,
“info” : {
“title” : “SteinwegHierarchy”,
“description” : “Steinweg Hierarchy REST API's”,
“version” : “1”
},
“basePath” : “/SteinwegHierarchy”,
“paths” : {
“/getLegalChildByGuid” : {
“get” : {
“tags” : [“SteinwegHierarchy”],
“description” : “Method to Get Legal Child By Guid”,
“operationId” : “getLegalChildByGuid”,
“produces” : [“application/json”],
“parameters” : [{
“name” : “Guid”,
“in” : “query”,
“required” : true,
“type” : “string”,
“default” : “”,
“description” : “Guid”
}
],
“responses” : {
“200” : {
“description” : “Method Response”,
“schema” : {
“$ref” : “#/definitions/STR_getSteinwegHierarchyList”
}
}
},
“security” : [{
“Authorization” : []
}
]
}
},
“/getLegalParentByGuid” : {
“get” : {
“tags” : [“SteinwegHierarchy”],
“description” : “Method to get legal parent by Guid.”,
“operationId” : “getLegalParentByGuid”,
“produces” : [“application/json”],
“parameters” : [{
“name” : “Guid”,
“in” : “query”,
“required” : true,
“type” : “string”,
“default” : “”,
“description” : “Guid”
}
],
“responses” : {
“200” : {
“description” : “Method Response.”,
“schema” : {
“$ref” : “#/definitions/STR_getSteinwegHierarchy”
}
}
},
“security” : [{
“Authorization” : []
}
]
}
},
“/getOperationalChildByGuid” : {
“get” : {
“tags” : [“SteinwegHierarchy”],
“description” : “Method to get operational child by Guid.”,
“operationId” : “getOperationalChildByGuid”,
“produces” : [“application/json”],
“parameters” : [{
“name” : “Guid”,
“in” : “query”,
“required” : true,
“type” : “string”,
“default” : “”,
“description” : “Guid”
}
],
“responses” : {
“200” : {
“description” : “Method response.”,
“schema” : {
“$ref” : “#/definitions/STR_getSteinwegHierarchyList”
}
}
},
“security” : [{
“Authorization” : []
}
]
}
},
“/getOperationalParentByGuid” : {
“get” : {
“tags” : [“SteinwegHierarchy”],
“description” : “Method to get operational parent by Guid.”,
“operationId” : “getOperationalParentByGuid”,
“produces” : [“application/json”],
“parameters” : [{
“name” : “Guid”,
“in” : “query”,
“required” : true,
“type” : “string”,
“default” : “”,
“description” : “Guid”
}
],
“responses” : {
“200” : {
“description” : “Method Response.”,
“schema” : {
“$ref” : “#/definitions/STR_getSteinwegHierarchy”
}
}
},
“security” : [{
“Authorization” : []
}
]
}
},
“/getSteinwegHierarchyByGuid” : {
“get” : {
“tags” : [“SteinwegHierarchy”],
“description” : “Method to get Steinweg Hierarchy by Guid.”,
“operationId” : “getSteinwegHierarchyByGuid”,
“produces” : [“application/json”],
“parameters” : [{
“name” : “Guid”,
“in” : “query”,
“required” : true,
“type” : “string”,
“default” : “”,
“description” : “Guid”
}
],
“responses” : {
“200” : {
“description” : “Method response.”,
“schema” : {
“$ref” : “#/definitions/STR_getSteinwegHierarchy”
}
}
},
“security” : [{
“Authorization” : []
}
]
}
},
“/getSteinwegHierarchyByType” : {
“get” : {
“tags” : [“SteinwegHierarchy”],
“description” : “Method to get Steinweg Hierarchies by Type”,
“operationId” : “getSteinwegHierarchyByType”,
“produces” : [“application/json”],
“parameters” : [{
“name” : “SteinwegHierarchyTypeId”,
“in” : “query”,
“required” : true,
“type” : “string”,
“default” : “”,
“description” : “Steinweg Hierarchy Type Identifier”
}
],
“responses” : {
“200” : {
“description” : “Method response.”,
“schema” : {
“$ref” : “#/definitions/STR_getSteinwegHierarchyList”
}
}
},
“security” : [{
“Authorization” : []
}
]
}
},
“/getSteinwegHierarchyComboList” : {
“get” : {
“tags” : [“SteinwegHierarchy”],
“description” : “”,
“operationId” : “getSteinwegHierarchyComboList”,
“produces” : [“application/json”],
“responses” : {
“200” : {
“description” : “Method response.”,
“schema” : {
“$ref” : “#/definitions/STR_getSteinwegHierarchyListCombo”
}
}
},
“security” : [{
“Authorization” : []
}
]
}
}
},
“definitions” : {
“ReturnMessage” : {
“description” : “If the call to the service was a success or not and the error message.”,
“type” : “object”,
“properties” : {
“Success” : {
“type” : “boolean”,
“example” : false,
“description” : “If is success.”
},
“ErrorMessage” : {
“$ref” : “#/definitions/STR_ErrorObject”
}
}
},
“STR_ErrorObject” : {
“description” : “”,
“type” : “object”,
“properties” : {
“trackingId” : {
“type” : “string”,
“default” : “”
},
“apiName” : {
“type” : “string”,
“default” : “”
},
“functionName” : {
“type” : “string”,
“default” : “”
},
“errorMessage” : {
“type” : “string”,
“default” : “”
},
“errorCode” : {
“type” : “integer”,
“example” : 1234567891234567,
“format” : “int64”
},
“errorDateTime” : {
“type” : “string”,
“format” : “date-time”,
“example” : “2014-12-31T23:59:59.938Z”
}
}
},
“STR_getSteinwegHierarchy” : {
“description” : “Structure to store the response from the GetGoodsCode method.”,
“type” : “object”,
“properties” : {
“ReturnMessage” : {
“$ref” : “#/definitions/ReturnMessage”
},
“SteinwegHierarchyRec” : {
“$ref” : “#/definitions/STR_SteinwegHierarchy2Api”
}
}
},
“STR_getSteinwegHierarchyList” : {
“description” : “Structure to store the response from the GetGoodsCode method.”,
“type” : “object”,
“properties” : {
“ReturnMessage” : {
“$ref” : “#/definitions/ReturnMessage”
},
“SteinwegHierarchyRecList” : {
“type” : “array”,
“items” : {
“$ref” : “#/definitions/STR_SteinwegHierarchy2Api”
},
“description” : “Steinweg Hierarchy Record List”
}
}
},
“STR_getSteinwegHierarchyListCombo” : {
“description” : “Structure to store the response from the GetGoodsCode method.”,
“type” : “object”,
“properties” : {
“ReturnMessage” : {
“$ref” : “#/definitions/ReturnMessage”
},
“SteinwegHierarchyComboList” : {
“type” : “array”,
“items” : {
“$ref” : “#/definitions/STR_SteinwegHierarchy2Combo”
},
“description” : “Steinweg Hierarchy Combo List”
}
}
},
“STR_SteinwegHierarchy2Api” : {
“description” : “Structure for the Steinweg Hierarchy to Rest API.”,
“type” : “object”,
“properties” : {
“Guid” : {
“type” : “string”,
“default” : “”,
“description” : “The Guid.”
},
“CompanyName” : {
“type” : “string”,
“default” : “”,
“description” : “The Company Name.”
},
“CompanyCode” : {
“type” : “string”,
“default” : “”,
“description” : “The Company Code.”
},
“SteinwegHierarchyTypeIdentifier” : {
“type” : “string”,
“default” : “”,
“description” : “The Steinweg Hierarchy Type Identifier.”
},
“SteinwegHierarchyType” : {
“type” : “string”,
“default” : “”,
“description” : “The Steinweg Hierarchy Type.”
},
“Api_manager_routing_post_fix” : {
“type” : “string”,
“default” : “”,
“description” : “Api manager routing postfix”
},
“CRM” : {
“type” : “boolean”,
“example” : false,
“description” : “CRM”
},
“Coda” : {
“type” : “boolean”,
“example” : false,
“description” : “Coda”
},
“OperationalParent_Guid” : {
“type” : “string”,
“default” : “”,
“description” : “Operational Parent”
},
“LegalParent_Guid” : {
“type” : “string”,
“default” : “”,
“description” : “LegalParent”
},
“Valid_till” : {
“type” : “string”,
“format” : “date-time”,
“example” : “2014-12-31T23:59:59.938Z”,
“description” : “Valid till”
},
“CompanyGuid” : {
“type” : “string”,
“default” : “”,
“description” : “Company Guid (if SteinwegHierarchy Type = Company)”
}
}
},
“STR_SteinwegHierarchy2Combo” : {
“description” : “Structure to Store Steinweg Hierarchy information for combo box”,
“type” : “object”,
“properties” : {
“Guid” : {
“type” : “string”,
“default” : “”,
“description” : “SteinwegHierarchy Guid”
},
“Description” : {
“type” : “string”,
“default” : “”,
“description” : “Description (Code + Name)”
}
}
}
},
“tags” : [{
“name” : “SteinwegHierarchy”
}
],
“host” : “APIMANAGERHOSTNAME”,
“securityDefinitions” : {
“Authorization” : {
“type” : “apiKey”,
“name” : “Authorization”,
“in” : “header”
}
}
}

Hi,
Sorry, but not sure I understood. Did you mean to say that you can’t upload the swagger to Tyk’s catalogue? or that you can’t execute the requests via the catalogue ?
Thank you

Hi Yaara,

I’m trying to say that i’m not able to execute a request succesfully. The error “TypeError: Failed to fetch” is always returned.

Kind regards,

Tim

I have imported the api and the swagger to the catalogue (after changing the target url and org_id).
I tested /getSteinwegHierarchyComboList and it looks like it’s working.
Can you specify what exactly are you sending?
Thanks,
Yaara

curl -X GET “https://letzit2.cloud.tyk.io/SteinwegHierarchy/getSteinwegHierarchyComboList” -H “accept: application/json” -H “Authorization: 59d27324b8125f000137663e4f159109e21046ca7c018c996ccc8224”

Response body:

{
“origin”: “151.228.199.234, 172.30.2.182, 172.30.2.111, 54.175.77.57”
}

Response headers:

access-control-allow-credentials: true access-control-allow-origin: https://letzit2.cloud.tyk.io, https://letzit2.cloud.tyk.io access-control-expose-headers: * content-type: application/json date: Fri, 10 Nov 2017 17:57:31 GMT server: meinheld/0.6.1 vary: Origin via: 1.1 vegur x-powered-by: Flask x-processed-time: 0.000478982925415 x-ratelimit-limit: 20 x-ratelimit-remaining: 16 x-ratelimit-reset: 1510340202 content-length: 76 connection: keep-alive

Hi Yaara,

Thanks for your reply. Please see the printscreens to show you exactly what I’m sending and receiving:

Kind regards,

Tim

Hi Yaara,

I’m able to reproduce this issue. Please add the header “Access-Control-Allow-Origin” with the value “*” to the response header.

Can you please try to reproduce this?

Kind regards,

Tim

Hi all,

I have investigated this issue further. I will try to explain this issue as best I can. The root cause of my error is the fact that the response message contains two “access-control-allow-origin” headers. Please see this link for more info:

In order to reproduce this issue, I performed the following steps:

  1. perform http request in tyk portal. The portal first performs an “OPTIONS” http preflight request to verify that the server will accept the request. Next Tyk will perform the “GET” http request to request the data. Both requests contain the “origin” header with the ip-adres of the portal. I will come back to this later.
    Both requests are processed from the tyk catalogue api to the tyk api itself and forwarded to the backend microservice.
  2. Our backend microservice returns the following http headers in the response message:
  • Cache-Control: no-cache
  • Pragma: no-cache
  • Content-Type: application/json; charset=utf-8
  • Expires: -1
  • Server: Microsoft-IIS/10.0
  • Access-Control-Allow-Origin: *
  • Date: Wed, 15 Nov 2017 15:45:49 GMT
  • Content-Length: 2
    As you can see, the backend microservice returns the “Access-Control-Allow-Origin” header with the value “*”. This response is returned to the Tyk api. The tyk api’s returns the http response back to the requesting application with the following http headers:
  • Access-Control-Allow-Origin: https://10.31.12.38:3000
  • Access-Control-Allow-Origin: *
  • and a lot more common http headers
    The “Access-Control-Allow-Origin” is defined twice in the http header. My assumption is that the tyk api itself adds another “Access-Control-Allow-Origin” while it is already is the http response message.

The reason why directly call the api itself works correctly instead of via the catalogue, is because the origin header is not added to the request message. In order to reproduce this issue at your side, you should make sure that the backend application returns the header “Access-Control-Allow-Origin” with the value “*”. Are you able to reproduce this issue at your side?

I hope that this makes things clear to reproduce this issue at your side. Please see the picture below to understand how we have set up our tyk environment with our microservice backend.

Kind regards,

Tim

Hi,
Sorry, couldn’t reproduce it. is it because my endpoint is http://httpbin.org?
Also why does your call responds with https://10.31.12.38:3000 ? isn’t 3000 the post of the dashboard?

Hi Yaara,

Correct, the url with port 3000 is the servername of the dashboard. I checked the endpoint “http://httpbin.org” and this website also returns the header “Access-Control-Allow-Origin” so it should be reproducible. I will try to reproduce it with the endpoint “http://httpbin.org” and come back with the results.

Kind regards,

Tim

Try to set options_passthrough to true (//tyk.io/docs/tyk-gateway-api/api-definition-objects/)

Thanks Yaara,

By setting the options_passthrough to “true” and set the CORS property to “false” solves this issue. Thanks for helping me with this issue.

Kind regards,

Tim

2 Likes