{"record":{"id":"f0ca77c6719f6382","repo":"RocketChat/Rocket.Chat","slug":"invalid-url-it-doesn-t-exist-or-is-not-applicati","errorCode":null,"errorMessage":"Invalid url. It doesn't exist or is not \"application/zip\".","messagePattern":"Invalid url\\. It doesn't exist or is not \"application/zip\"\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/apps/communication/rest.ts","lineNumber":327,"sourceCode":"\t\t\t\t\t\t\t\t\t.catch((cause) => {\n\t\t\t\t\t\t\t\t\t\tthrow new Error('App package download failed', { cause });\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tApps.getMarketplaceClient()\n\t\t\t\t\t\t\t\t\t.fetch(`v1/apps/${this.bodyParams.appId}?appVersion=${this.bodyParams.version}`, {\n\t\t\t\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\t\t\tAuthorization: `Bearer ${marketplaceToken}`,\n\t\t\t\t\t\t\t\t\t\t\t...headers,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t// SECURITY: user needs specific privileges to send this. Bypassing the SSRF check is okay for now.\n\t\t\t\t\t\t\t\t\t\tignoreSsrfValidation: true,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.catch((cause) => {\n\t\t\t\t\t\t\t\t\t\tthrow new Error('App metadata download failed', { cause });\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t]);\n\n\t\t\t\t\t\t\tif (downloadResponse.headers.get('content-type') !== 'application/zip') {\n\t\t\t\t\t\t\t\tthrow new Error('Invalid url. It doesn\\'t exist or is not \"application/zip\".');\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbuff = Buffer.from(await downloadResponse.arrayBuffer());\n\t\t\t\t\t\t\tmarketplaceInfo = await marketplaceResponse.json();\n\n\t\t\t\t\t\t\t// Note: marketplace responds with an array of the marketplace info on the app, but it is expected\n\t\t\t\t\t\t\t// to always have one element since we are fetching a specific app version.\n\t\t\t\t\t\t\tif (!Array.isArray(marketplaceInfo) || marketplaceInfo?.length !== 1) {\n\t\t\t\t\t\t\t\torchestrator.getRocketChatLogger().error({ msg: 'Error getting app information from marketplace', marketplaceInfo });\n\t\t\t\t\t\t\t\tthrow new Error('Invalid response from the Marketplace');\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tpermissionsGranted = this.bodyParams.permissionsGranted;\n\t\t\t\t\t\t} catch (err: unknown) {\n\t\t\t\t\t\t\tlet message;\n\n\t\t\t\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\t\t\t\torchestrator.getRocketChatLogger().error({ msg: 'Error installing app from marketplace:', err });","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/apps/communication/rest.ts#L309-L345","documentation":"Thrown after both marketplace fetches succeed (the promises did not reject) but the download response's Content-Type header is not exactly 'application/zip'. The marketplace returned something that is not a zip package, so the buffer step is unsafe and the install aborts. Distinct from errors 184/185 which fire when the fetch promise itself rejects.","triggerScenarios":"POST /api/v1/apps marketplace install where the marketplace download endpoint returns 200 but with a different content type (e.g. text/html error page, application/json, application/gzip, or a redirect to an HTML login page).","commonSituations":"Marketplace returns an HTML error/landing page with a 200 status instead of failing properly; a man-in-the-middle or captive proxy returns HTML; the app version is a legacy non-zip artifact; content negotiation returned a gzipped stream.","solutions":["Inspect the marketplace response manually (the server logs the full error path); identify what content type was returned.","If a proxy is intercepting, add the marketplace host to proxy bypass or configure HTTPS_PROXY correctly.","Retry against a known-good app version to isolate whether the artifact itself is malformed.","Report to marketplace ops if a valid version consistently returns non-zip content."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function assertZipContentType(headers: Headers) {\n  if (headers.get('content-type') !== 'application/zip') {\n    throw new Error(`Expected application/zip, got ${headers.get('content-type')}`);\n  }\n}","typeGuard":"const isZipResponse = (res: Response): boolean =>\n  res.headers.get('content-type') === 'application/zip';","tryCatchPattern":"try {\n  await installMarketplaceApp(appId, version);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('application/zip')) {\n    // marketplace returned non-zip; likely an HTML error page or proxy interception\n    investigateProxyOrMarketplaceStatus();\n  }\n}","preventionTips":["If behind a proxy, ensure it does not rewrite/replace marketplace responses with HTML.","Validate content-type of marketplace responses in a diagnostic before relying on them.","Report consistent non-zip returns for a valid version to marketplace operations."],"tags":["apps-engine","marketplace","content-type","install"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}