{"record":{"id":"d3a7ab73ba9c610a","repo":"RocketChat/Rocket.Chat","slug":"failed-to-connect-to-rocket-chat-cloud-response","errorCode":null,"errorMessage":"Failed to connect to Rocket.Chat Cloud: ${response.statusText}","messagePattern":"Failed to connect to Rocket\\.Chat Cloud: (.+?)","errorType":"exception","errorClass":"CloudWorkspaceConnectionError","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/lib/cloud/connectWorkspace.ts","lineNumber":37,"sourceCode":"\t};\n}) => {\n\tconst cloudUrl = settings.get<string>('Cloud_Url');\n\tconst response = await fetch(`${cloudUrl}/api/oauth/clients`, {\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${token}`,\n\t\t},\n\t\tbody,\n\t\t// SECURITY: the URL is a default hardcoded value or an envvar/setting set by an admin. It's safe to disable this check.\n\t\tignoreSsrfValidation: true,\n\t});\n\n\tif (!response.ok) {\n\t\ttry {\n\t\t\tconst { error } = await response.json();\n\t\t\tthrow new CloudWorkspaceConnectionError(`Failed to connect to Rocket.Chat Cloud: ${error}`);\n\t\t} catch (error) {\n\t\t\tthrow new CloudWorkspaceConnectionError(`Failed to connect to Rocket.Chat Cloud: ${response.statusText}`);\n\t\t}\n\t}\n\n\tconst payload = await response.json();\n\n\tif (!payload) {\n\t\treturn undefined;\n\t}\n\n\treturn payload;\n};\n\nexport async function connectWorkspace(token: string) {\n\tassertNotOfflineLicense();\n\n\tif (!token) {\n\t\tthrow new CloudWorkspaceConnectionError('Invalid registration token');\n\t}","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/cloud/connectWorkspace.ts#L19-L55","documentation":"The same non-ok branch in fetchRegistrationDataPayload, but response.json() threw because the body is not JSON, so the error falls back to the HTTP statusText ('Bad Gateway', 'Service Unavailable', ...). It means something other than the cloud API answered the request — typically an intermediary proxy, firewall, or the wrong Cloud_Url.","triggerScenarios":"A corporate proxy, captive portal, WAF, or TLS inspection device intercepts the call to the cloud register endpoint and returns an HTML/plain-text error page; or Cloud_Url is misconfigured so a generic web server answers 404/500.","commonSituations":"Egress-restricted networks with HTTP(S) inspection; Cloud_Url typos; cloud maintenance pages; gateway 502/503 during outages.","solutions":["From the server, curl -v the Cloud_Url registration endpoint to see who is actually answering and with what content-type.","Allowlist the cloud URL on proxies/firewalls and exempt it from TLS inspection.","Fix the Cloud_Url setting to the correct cloud API base URL.","If the cloud itself is down (502/503), retry later."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const probe = await fetch(`${cloudUrl}/api/v2/register/workspace`, { method: 'OPTIONS' });\nif (!probe.ok) {\n  throw new Error(`cloud unreachable via ${cloudUrl}: ${probe.status} — check proxy/Cloud_Url`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await connectWorkspace(token);\n} catch (e) {\n  if (e instanceof CloudWorkspaceConnectionError && /Bad Gateway|Service Unavailable|Forbidden/.test(e.message)) {\n    // non-JSON intermediary response: inspect proxy/egress path, not cloud app logic\n  }\n  throw e;\n}","preventionTips":["Smoke-test the cloud URL from the server (curl -v) before running registration flows.","Exempt cloud endpoints from TLS inspection and HTML error pages on egress proxies.","Alert on non-2xx non-JSON responses to distinguish infrastructure issues from cloud rejections."],"tags":["rocket-chat","cloud","proxy","http-status"],"backgroundTag":"http-non-json-error-response","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}