SonarSource/sonarqube · error · IllegalStateException

"Cannot open file " + propsFile

Error message

"Cannot open file " + propsFile

What it means

Shutdowner.loadPropertiesFile reads ${homeDir}/conf/sonar.properties as UTF-8 into a Properties object. If the file exists but reading fails (IOException), it throws IllegalStateException "Cannot open file <path>". Note loadPropertiesFile only reaches the read when propsFile.exists() is true; the error indicates an I/O problem, not a missing file.

Source

Thrown at sonar-shutdowner/src/main/java/org/sonar/application/Shutdowner.java:77

      return appJar.getParentFile().getParentFile();
    } catch (URISyntaxException e) {
      throw new IllegalStateException("Cannot detect path of shutdowner jar file", e);
    }
  }

  /**
   * Loads the configuration file ${homeDir}/conf/sonar.properties.
   * An empty {@link Properties} is returned if the file does not exist.
   */
  static Properties loadPropertiesFile(File homeDir) {
    Properties p = new Properties();
    File propsFile = new File(new File(homeDir, "conf"), "sonar.properties");
    if (propsFile.exists()) {
      try (Reader reader = new InputStreamReader(new FileInputStream(propsFile), UTF_8)) {
        p.load(reader);
        return p;
      } catch (IOException e) {
        throw new IllegalStateException("Cannot open file " + propsFile, e);
      }
    } else {
      throw new IllegalStateException("Configuration file not found: " + propsFile);
    }
  }

  static File resolveTempDir(Properties p) {
    return new File(Optional.ofNullable(p.getProperty("sonar.path.temp")).orElse("temp"));
  }

  static void askForHardStop(File tmpDir) throws IOException {
    writeToShareMemory(tmpDir, 1, (byte) 0xFF);
  }

  private static void writeToShareMemory(File tmpDir, int offset, byte value) throws IOException {
    try (RandomAccessFile sharedMemory = new RandomAccessFile(new File(tmpDir, "sharedmemory"), "rw")) {
      // Using values from org.sonar.process.ProcessCommands
      MappedByteBuffer mappedByteBuffer = sharedMemory.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 50L * 10);

View on GitHub (pinned to 184c821202)

Solutions

  1. Fix file permissions so the shutdowner's user can read ${SONARQUBE_HOME}/conf/sonar.properties (e.g. chmod 640, correct owner).
  2. Close/stop the other process holding a lock on the file (Windows).
  3. Verify the path is a regular file, not a directory or symlink to an unreadable target.
  4. Check the wrapped IOException cause for the precise OS-level error.

Example fix

// before
$ ls -l conf/sonar.properties
-rw------- 1 root root conf/sonar.properties

// after: grant read access to the sonarqube user
$ sudo chown sonarqube:sonarqube conf/sonar.properties
$ sudo chmod 640 conf/sonar.properties
Defensive patterns

Strategy: try-catch

Validate before calling

// Java
File propsFile = new File(new File(homeDir, "conf"), "sonar.properties");
if (!propsFile.isFile() || !propsFile.canRead()) {
  throw new IllegalStateException("Cannot read config file: " + propsFile);
}

Try / catch

// Java
try {
  Properties p = shutdowner.p();
} catch (IllegalStateException e) {
  // inspect cause (IOException): fix permissions or file lock, then retry
}

Prevention

When it happens

Trigger: Calling p() -> loadPropertiesFile() when conf/sonar.properties exists but cannot be read: permission denied, file locked by another process, or an IO error during load.

Common situations: conf/sonar.properties owned by another user with restrictive permissions; running the shutdowner as a service account lacking read access; the file being a directory or locked on Windows.

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/60f272a2e9359dbd. Report an issue: GitHub.