questdb/questdb · critical · BootstrapException
Could not extract log configuration file
Error message
Could not extract log configuration file
What it means
Thrown when copyLogConfResource() raises an IOException while extracting the bundled log configuration resource into the root directory. Before the logger starts, Bootstrap copies the default log.conf into <root>/conf/log.conf; any I/O failure during that copy (unwritable dir, disk full, missing classpath resource) surfaces as this generic message.
Source
Thrown at core/src/main/java/io/questdb/Bootstrap.java:130
rootDirectory = argsMap.get("-d");
if (Chars.isBlank(rootDirectory)) {
throw new BootstrapException("Root directory name expected (-d <root-path>)");
}
final File rootPath = new File(rootDirectory);
if (!rootPath.exists()) {
throw new BootstrapException("Root directory does not exist: " + rootDirectory);
}
if (argsMap.get("-n") == null && Os.type != Os.WINDOWS) {
Signal.handle(new Signal("HUP"), _ -> { /* suppress HUP signal */ });
}
// before we set up the logger, we need to copy the conf file
byte[] buffer = new byte[1024 * 1024];
try {
copyLogConfResource(buffer);
} catch (IOException e) {
throw new BootstrapException("Could not extract log configuration file");
}
// setup logger
// note: this call must be made before any Log init.
if (argsMap.get(SWITCH_USE_DEFAULT_LOG_FACTORY_CONFIGURATION) == null) {
LogFactory.configureRootDir(rootDirectory);
}
log = LogFactory.getLog(LOG_NAME);
try {
copyResource(rootDirectory, false, buffer, "import/readme.txt", log);
copyResource(rootDirectory, false, buffer, "import/trades.parquet", log);
} catch (IOException e) {
throw new BootstrapException("Could not create the default import directory");
}
// report copyright and architecture
log.advisoryW()View on GitHub (pinned to 6610ab113b)
Solutions
- Ensure the user running QuestDB has write permission on the root dir: chown -R questdb: /var/lib/questdb or chmod u+w
- Check disk space (df -h <root>) and free space if full
- If using a custom/shaded build, verify the log conf resource is packaged on the classpath, or pass the switch that skips copying and use LogFactory's default configuration
Example fix
# before: root owned by root, server runs as questdb ls -ld /var/lib/questdb # drwxr-xr-x root root # after chown -R questdb:questdb /var/lib/questdb
Defensive patterns
Strategy: validation
Validate before calling
File confDir = new File(rootDir, "conf");
if (!confDir.exists() && !confDir.mkdirs()) {
throw new IllegalStateException("Cannot create or write " + confDir + " - check permissions/disk");
}
new Bootstrap(Bootstrap.getServerMainArgs(rootDir)); Try / catch
try {
bootstrap = new Bootstrap(args);
} catch (Bootstrap.BootstrapException e) {
// I/O environment problem: fix filesystem (perms/space), restart the JVM
} Prevention
- Pre-create <root>/conf with correct ownership in provisioning scripts
- Monitor disk usage on the root volume so copies never fail from ENOSPC
When it happens
Trigger: Root directory exists but the <root>/conf subdirectory cannot be created or written (read-only filesystem, no write permission, SELinux denial); disk full; or a repackaged/shaded jar where the log conf resource is missing from the classpath.
Common situations: Running QuestDB against a root dir owned by another user; Docker read-only volume mounts; minimal/shaded jars built without resources; disk exhaustion.
Related errors
- Could not create the default import directory
- Server configuration file exists, but is not readable! Check
- Root directory name expected (-d <root-path>)
- Root directory does not exist: ${rootDirectory}
- Server configuration file does not exist! ${configFile}
AI-assisted analysis of questdb/questdb@6610ab113b (2026-08-14).
Data as JSON: /api/errors/76b06d85e7434646.
Report an issue: GitHub.