SonarSource/sonarqube · critical · IllegalStateException
Fail to create or clean-up directory %s
Error message
Fail to create or clean-up directory %s
What it means
TomcatContexts.addStaticDir serves SonarQube's static content from a filesystem directory. It first calls Fs.createOrCleanupDir (forcing directory creation/cleanup via FileUtils.forceMkdir); if that raises IOException, the directory could not be created or cleaned and an IllegalStateException wrapping it is thrown, failing server startup.
Source
Thrown at server/sonar-webserver/src/main/java/org/sonar/server/app/TomcatContexts.java:94
}
static String getContextPath(Props props) {
String context = props.value(WEB_CONTEXT.getKey(), "");
if ("/".equals(context)) {
context = "";
} else if (!"".equals(context) && context != null && !context.startsWith("/")) {
throw MessageException.of(format("Value of '%s' must start with a forward slash: '%s'", WEB_CONTEXT.getKey(), context));
}
return context;
}
@VisibleForTesting
StandardContext addStaticDir(Tomcat tomcat, String contextPath, File dir) {
try {
fs.createOrCleanupDir(dir);
configureDeployErrorPages(dir, contextPath);
} catch (IOException e) {
throw new IllegalStateException(format("Fail to create or clean-up directory %s", dir.getAbsolutePath()), e);
}
return addContext(tomcat, contextPath, dir);
}
private static StandardContext addContext(Tomcat tomcat, String contextPath, File dir) {
try {
StandardContext context = (StandardContext) tomcat.addWebapp(contextPath, dir.getAbsolutePath());
context.setClearReferencesHttpClientKeepAliveThread(false);
context.setClearReferencesStopThreads(false);
context.setClearReferencesStopTimerThreads(false);
context.setClearReferencesStopTimerThreads(false);
context.setAntiResourceLocking(false);
context.setReloadable(false);
context.setUseHttpOnly(true);
context.setTldValidation(false);
context.setXmlValidation(false);
context.setXmlNamespaceAware(false);View on GitHub (pinned to 184c821202)
Solutions
- Check permissions on the directory's parent and ensure the sonar process user can write there; chown/chmod as needed
- Delete any plain FILE named like the expected directory so it can be created as a directory
- Ensure the volume is writable and has free space (Docker: use a writable volume, not a read-only mount)
Example fix
// before sudo -u otheruser ./sonar.sh start # user can't write to install dir // after sudo chown -R sonar:sonar /opt/sonarqube && sudo -u sonar ./sonar.sh start
Defensive patterns
Strategy: validation
Validate before calling
File dir = new File(home, "web");
if (dir.exists() && !dir.isDirectory()) throw new IllegalStateException(dir + " exists and is not a directory");
if (!dir.exists() && !dir.getParentFile().canWrite()) throw new IllegalStateException("No write permission on " + dir.getParentFile()); Try / catch
try { server.start(); } catch (IllegalStateException e) { if (e.getMessage().contains("Fail to create or clean-up directory")) { log.error("Check permissions/ownership of the SonarQube install dir for the process user"); } throw e; } Prevention
- Run SonarQube as a user owning its installation directory (chown -R)
- Avoid installing into read-only volumes or Docker read-only mounts
- Do not place plain files where directories (e.g. 'web') are expected
When it happens
Trigger: The static-content directory (e.g. $SONARQUBE_HOME/web) cannot be created because of insufficient filesystem permissions, a read-only volume, or because a non-directory FILE already exists at that path (cleanup fails).
Common situations: Running the SonarQube process as a user without write access to the installation directory; installing over an existing 'web' file; read-only Docker layer or mounted volume; disk full.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- Failed to create directory %s
- Property '%s' is not valid, not a directory: %s
- Directory '%s' is a file
- '%s' is not a directory
- Failed to configure ROOT context
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/d99f18f7e60550ff.
Report an issue: GitHub.