{"record":{"id":"fde882815615e492","repo":"SonarSource/sonarqube","slug":"plugin-s-not-found","errorCode":null,"errorMessage":"Plugin %s not found","messagePattern":"Plugin (.+?) not found","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/plugins/ws/DownloadAction.java","lineNumber":67,"sourceCode":"      .setInternal(true)\n      .setContentType(Response.ContentType.BINARY)\n      .setHandler(this);\n\n    action.createParam(PLUGIN_PARAM)\n      .setRequired(true)\n      .setDescription(\"The key identifying the plugin to download\")\n      .setExampleValue(\"cobol\");\n\n    action.setChangelog(new Change(\"9.8\", \"Parameter 'acceptCompressions' removed\"));\n  }\n\n  @Override\n  public void handle(Request request, Response response) throws Exception {\n    String pluginKey = request.mandatoryParam(PLUGIN_PARAM);\n\n    Optional<ServerPlugin> file = pluginRepository.findPlugin(pluginKey);\n    if (!file.isPresent()) {\n      throw new NotFoundException(\"Plugin \" + pluginKey + \" not found\");\n    }\n\n    FileAndMd5 downloadedFile;\n\n    response.stream().setMediaType(\"application/java-archive\");\n    downloadedFile = file.get().getJar();\n\n    response.setHeader(\"Sonar-MD5\", downloadedFile.getMd5());\n    try (InputStream input = FileUtils.openInputStream(downloadedFile.getFile())) {\n      IOUtils.copyLarge(input, response.stream().output());\n    }\n  }\n}\n","sourceCodeStart":49,"sourceCodeEnd":81,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/plugins/ws/DownloadAction.java#L49-L81","documentation":"DownloadAction serves api/plugins/download, streaming a plugin's JAR from the server's plugin repository. If no installed server plugin matches the requested plugin key, the plugin is not present in the local repository and the action throws NotFoundException.","triggerScenarios":"GET api/plugins/download?plugin=<key> where <key> is misspelled, refers to a plugin that is not installed on this server, or was uninstalled/pending removal (plugin JAR not currently loaded in the repository).","commonSituations":"Scripts downloading plugin JARs after an update-center listing where the key from the marketplace differs from the installed key; downloading a plugin that is only bundled (e.g. commercial edition) and thus not in the server plugin repository; stale automation referencing an uninstalled plugin.","solutions":["Verify the plugin key with GET api/plugins/installed (or api/plugins/available) and use the exact key returned.","If the plugin should be installed, install it first (marketplace UI or api/plugins/install) and retry the download.","If the plugin was just uninstalled or is pending a restart, restart the server so the repository state matches, or download the JAR from the update center instead."],"exampleFix":"// before\nconst jar = await api.plugins.download({ plugin: 'sonar-go-plugin' });\n// after\nconst installed = await api.plugins.installed();\nconst p = installed.plugins.find(p => p.key === 'sonar-go-plugin');\nif (!p) throw new Error(`plugin not installed: ${key}`);\nconst jar = await api.plugins.download({ plugin: p.key });","handlingStrategy":"validation","validationCode":"const installed = (await api.plugins.installed()).plugins;\nconst plugin = installed.find(p => p.key === key);\nif (!plugin) throw new Error(`plugin ${key} not installed; cannot download`);","typeGuard":"function isInstalled(plugins, key) {\n  return Array.isArray(plugins) && plugins.some(p => p && p.key === key);\n}","tryCatchPattern":"try {\n  return await api.plugins.download({ plugin: key });\n} catch (e) {\n  if (e.status === 404) {\n    throw new Error(`plugin '${key}' not found on server; check api/plugins/installed`);\n  }\n  throw e;\n}","preventionTips":["Fetch api/plugins/installed first and use exact keys from its response.","Handle pending-install/pending-uninstall states before downloading.","Prefer the update center artifacts for plugins not installed on the server."],"tags":["sonarqube","webapi","plugin","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}