{"record":{"id":"afb1bee1b3e4e06f","repo":"SonarSource/sonarqube","slug":"fail-to-extract-plugin-metadata-from-file","errorCode":null,"errorMessage":"Fail to extract plugin metadata from file: ","messagePattern":"Fail to extract plugin metadata from file: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java","lineNumber":372,"sourceCode":"  public int hashCode() {\n    return Objects.hash(key, version);\n  }\n\n  @Override\n  public int compareTo(PluginInfo that) {\n    return ComparisonChain.start()\n      .compare(this.name, that.name)\n      .compare(this.version, that.version, Ordering.natural().nullsFirst())\n      .result();\n  }\n\n  public static PluginInfo create(File jarFile) {\n    try {\n      PluginManifest manifest = new PluginManifest(jarFile);\n      return create(jarFile, manifest);\n\n    } catch (IOException e) {\n      throw new IllegalStateException(\"Fail to extract plugin metadata from file: \" + jarFile, e);\n    }\n  }\n\n  @VisibleForTesting\n  static PluginInfo create(File jarFile, PluginManifest manifest) {\n    validateManifest(jarFile, manifest);\n    PluginInfo info = new PluginInfo(manifest.getKey());\n    info.fillFields(jarFile, manifest);\n    return info;\n  }\n\n  private static void validateManifest(File jarFile, PluginManifest manifest) {\n    if (StringUtils.isBlank(manifest.getKey())) {\n      throw MessageException.of(String.format(\"File is not a plugin. Please delete it and restart: %s\", jarFile.getAbsolutePath()));\n    }\n  }\n\n  protected void fillFields(File jarFile, PluginManifest manifest) {","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java#L354-L390","documentation":"PluginInfo.create() throws this IllegalStateException when reading the plugin JAR's manifest fails with an IOException, e.g. the file is not a readable JAR, is corrupted, or the manifest cannot be opened. SonarQube uses the manifest to extract plugin metadata (key, version, required server version), so it aborts plugin loading when extraction fails.","triggerScenarios":"Calling PluginInfo.create(File) on a file that is not a valid ZIP/JAR, has a truncated/corrupt central directory, unreadable permissions, or whose META-INF/MANIFEST.MF cannot be read as a stream.","commonSituations":"Incomplete upload of a plugin JAR; a plugin jar corrupted on disk or truncated download; plugins directory containing non-jar files renamed to .jar; disk/permission problems in SONARQUBE_HOME/extensions/plugins.","solutions":["Verify the JAR is a valid zip: run 'unzip -t my-plugin.jar' or re-download it from the official source.","Remove or replace the corrupted JAR in the plugins directory and restart the server.","Check file permissions so the SonarQube process user can read the file.","Compare file size/checksum against the published artifact to confirm a complete download."],"exampleFix":"// before: jar truncated during copy\n$ cp my-plugin.jar extensions/plugins/\n// after: verify integrity first\n$ unzip -t my-plugin.jar && cp my-plugin.jar extensions/plugins/","handlingStrategy":"validation","validationCode":"if (!jarFile.isFile() || !jarFile.canRead() || !jarFile.getName().endsWith(\".jar\")) {\n  throw new IllegalArgumentException(\"Not a readable JAR: \" + jarFile);\n}\ntry (var zf = new java.util.zip.ZipFile(jarFile)) {\n  if (zf.getEntry(\"META-INF/MANIFEST.MF\") == null) {\n    throw new IllegalArgumentException(\"No manifest in JAR: \" + jarFile);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  PluginInfo info = PluginInfo.create(jarFile);\n} catch (IllegalStateException e) {\n  log.warn(\"Skipping corrupted plugin JAR {}: {}\", jarFile, e.getMessage());\n}","preventionTips":["Verify checksums of downloaded plugin JARs before deploying.","Test each JAR with 'unzip -t' as part of deployment automation.","Ensure the server process user has read access to the plugins directory."],"tags":["plugin-loading","jar-manifest","corrupt-file"],"backgroundTag":"file-read-failed","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}