{"record":{"id":"2858c1968d2e3ac9","repo":"n8n-io/n8n","slug":"gateway-rejected-token-status-body","errorCode":null,"errorMessage":"Gateway rejected token: ${status} ${body}","messagePattern":"Gateway rejected token: (.+?) (.+?)","errorType":"exception","errorClass":"GatewayAuthError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/computer-use/src/gateway-client.ts","lineNumber":316,"sourceCode":"\t\tconst url = `${this.options.url}/rest/instance-ai/gateway/init`;\n\t\tconst headers = new Headers();\n\t\theaders.set('Content-Type', 'application/json');\n\t\theaders.set('X-Gateway-Key', this.apiKey);\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: 'POST',\n\t\t\theaders,\n\t\t\tbody: JSON.stringify({\n\t\t\t\trootPath: this.dir,\n\t\t\t\ttools,\n\t\t\t\thostIdentifier: `${os.userInfo().username}@${os.hostname()}`,\n\t\t\t\ttoolCategories: this.activeToolCategories,\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text();\n\t\t\tif (response.status === 401 || response.status === 403) {\n\t\t\t\tthrow new GatewayAuthError(response.status, text);\n\t\t\t}\n\t\t\tthrow new Error(`Failed to upload capabilities: ${response.status} ${text}`);\n\t\t}\n\n\t\t// If the server returned a session key, switch to it for all subsequent requests\n\t\t// n8n wraps controller responses in { data: ... }\n\t\tconst body = (await response.json()) as { data: { ok: boolean; sessionKey?: string } };\n\t\tif (body.data.sessionKey) {\n\t\t\tthis.sessionKey = body.data.sessionKey;\n\t\t\tlogger.debug('Pairing token consumed, switched to session key');\n\t\t}\n\n\t\tlogger.debug('Capabilities uploaded', { toolCount: tools.length });\n\t}\n\n\tprivate connectSSE(): void {\n\t\tconst url = `${this.options.url}/rest/instance-ai/gateway/events`;\n","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/computer-use/src/gateway-client.ts#L298-L334","documentation":"GatewayAuthError thrown by uploadCapabilities() when the instance-ai gateway returns 401 or 403 for the X-Gateway-Key pairing token. The error has name 'GatewayAuthError', .status, and .body fields. This is an authentication failure at the gateway init endpoint — the pairing token is invalid, expired, or revoked.","triggerScenarios":"The pairing token (apiKey) is expired, revoked, or was generated for a different instance. The gateway URL points to a different n8n instance. Instance AI / MCP gateway is disabled on the server. The server restarted and invalidated pairing tokens.","commonSituations":"Long gap between pairing and tool registration causing token expiry, wrong gateway URL in config, instance restart, clipboard copy error on the token.","solutions":["Re-run the pairing flow to obtain a fresh gateway key","Verify the gateway URL (options.url) matches the target n8n instance","Confirm Instance AI / MCP gateway is enabled on the n8n server","Check the n8n server logs for gateway auth rejection details"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":"import { GatewayAuthError } from './gateway-client';\n\nfunction isGatewayAuthError(e: unknown): e is GatewayAuthError {\n  return e instanceof GatewayAuthError;\n}","tryCatchPattern":"try {\n  await gatewayClient.start();\n} catch (e) {\n  if (e instanceof GatewayAuthError) {\n    // e.status (401 or 403), e.body (server response text)\n    printAuthFailure(e);\n    // Re-pair to get a fresh token\n    await rePairGateway();\n  } else {\n    throw e;\n  }\n}","preventionTips":["Re-pair the gateway if there is a long gap between pairing and use","Verify the gateway URL matches the target n8n instance before connecting","Handle GatewayAuthError by triggering a re-pair flow rather than retrying with the same token"],"tags":["gateway","authentication","computer-use"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}