SonarSource/sonarqube · error · IllegalStateException

Fail to extract plugin metadata from file:

Error message

Fail to extract plugin metadata from file: 

What it means

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.

Source

Thrown at sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java:372

  public int hashCode() {
    return Objects.hash(key, version);
  }

  @Override
  public int compareTo(PluginInfo that) {
    return ComparisonChain.start()
      .compare(this.name, that.name)
      .compare(this.version, that.version, Ordering.natural().nullsFirst())
      .result();
  }

  public static PluginInfo create(File jarFile) {
    try {
      PluginManifest manifest = new PluginManifest(jarFile);
      return create(jarFile, manifest);

    } catch (IOException e) {
      throw new IllegalStateException("Fail to extract plugin metadata from file: " + jarFile, e);
    }
  }

  @VisibleForTesting
  static PluginInfo create(File jarFile, PluginManifest manifest) {
    validateManifest(jarFile, manifest);
    PluginInfo info = new PluginInfo(manifest.getKey());
    info.fillFields(jarFile, manifest);
    return info;
  }

  private static void validateManifest(File jarFile, PluginManifest manifest) {
    if (StringUtils.isBlank(manifest.getKey())) {
      throw MessageException.of(String.format("File is not a plugin. Please delete it and restart: %s", jarFile.getAbsolutePath()));
    }
  }

  protected void fillFields(File jarFile, PluginManifest manifest) {

View on GitHub (pinned to 184c821202)

Solutions

  1. Verify the JAR is a valid zip: run 'unzip -t my-plugin.jar' or re-download it from the official source.
  2. Remove or replace the corrupted JAR in the plugins directory and restart the server.
  3. Check file permissions so the SonarQube process user can read the file.
  4. Compare file size/checksum against the published artifact to confirm a complete download.

Example fix

// before: jar truncated during copy
$ cp my-plugin.jar extensions/plugins/
// after: verify integrity first
$ unzip -t my-plugin.jar && cp my-plugin.jar extensions/plugins/
Defensive patterns

Strategy: validation

Validate before calling

if (!jarFile.isFile() || !jarFile.canRead() || !jarFile.getName().endsWith(".jar")) {
  throw new IllegalArgumentException("Not a readable JAR: " + jarFile);
}
try (var zf = new java.util.zip.ZipFile(jarFile)) {
  if (zf.getEntry("META-INF/MANIFEST.MF") == null) {
    throw new IllegalArgumentException("No manifest in JAR: " + jarFile);
  }
}

Try / catch

try {
  PluginInfo info = PluginInfo.create(jarFile);
} catch (IllegalStateException e) {
  log.warn("Skipping corrupted plugin JAR {}: {}", jarFile, e.getMessage());
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/afb1bee1b3e4e06f. Report an issue: GitHub.