louislam/dockge · critical · Error
Fatal error: ${this.config.dataDir} is not a directory
Error message
Fatal error: ${this.config.dataDir} is not a directory What it means
initDataDir ensures the configured data directory exists, then lstats it and requires it to be a directory; otherwise it throws 'Fatal error: <dataDir> is not a directory'. This guards against the dataDir path existing but being a regular file, symlink to a file, socket, etc., which would break all subsequent file writes (db-config.json, stacks dir, sqlite db).
Source
Thrown at backend/dockge-server.ts:554
checkTimezone(timezone : string) {
try {
dayjs.utc("2013-11-18 11:55").tz(timezone).format();
} catch (e) {
throw new Error("Invalid timezone:" + timezone);
}
}
/**
* Initialize the data directory
*/
initDataDir() {
if (! fs.existsSync(this.config.dataDir)) {
fs.mkdirSync(this.config.dataDir, { recursive: true });
}
// Check if a directory
if (!fs.lstatSync(this.config.dataDir).isDirectory()) {
throw new Error(`Fatal error: ${this.config.dataDir} is not a directory`);
}
// Create data/stacks directory
if (!fs.existsSync(this.stacksDir)) {
fs.mkdirSync(this.stacksDir, { recursive: true });
}
log.info("server", `Data Dir: ${this.config.dataDir}`);
}
/**
* Init or reset JWT secret
* @returns JWT secret
*/
async initJWTSecret() : Promise<Bean> {
let jwtSecretBean = await R.findOne("setting", " `key` = ? ", [
"jwtSecret",
]);View on GitHub (pinned to f809ae192b)
Solutions
- Remove or rename the file at the configured dataDir path and create a directory there: mkdir -p /app/data
- Fix the --data-dir flag / DOCKGE_DATA_DIR env to point at a directory
- In Docker, mount a host directory (or named volume), not a single file: -v ./dockge-data:/app/data
Example fix
// before docker run -v ./dockge.db:/app/data dockge/dockge // after docker run -v ./dockge-data:/app/data dockge/dockge
Defensive patterns
Strategy: validation
Validate before calling
const fs = require("fs");
const st = fs.existsSync(dataDir) ? fs.lstatSync(dataDir) : null;
if (st && !st.isDirectory()) { throw new Error(`${dataDir} exists but is not a directory; move it and create a directory`); }
if (!st) fs.mkdirSync(dataDir, { recursive: true }); Type guard
function isDirectoryPath(p) { try { return fs.lstatSync(p).isDirectory(); } catch { return false; } } Try / catch
try { server.initDataDir(); } catch (e) { if (String(e.message).includes("is not a directory")) { console.error("Fix --data-dir / DOCKGE_DATA_DIR:", e.message); process.exit(1); } throw e; } Prevention
- In Docker, mount directories/named volumes, never single files, at the data dir path
- Verify the dataDir config with `ls -la` before starting
- Do not extract backups directly over the data dir path
- Use explicit DOCKGE_DATA_DIR rather than relying on defaults
When it happens
Trigger: --data-dir / DOCKGE_DATA_DIR (or config stack dir) points at a regular file; a file was accidentally created at the path (e.g. docker run mounted a single file where a dir was expected); a broken/symlink loop causing lstat to throw.
Common situations: Docker: '-v ./data.txt:/app/data' mounting a file as the data dir; typo in path where an existing filename matches; restore from backup extracted a file at the dataDir path.
Related errors
- Stack name must be a string.
- Service name must be a string.
- Shell must be a string.
- Invalid db-config.json, it must be an object
- Invalid db-config.json, type must be a string
AI-assisted analysis of louislam/dockge@f809ae192b (2026-08-31).
Data as JSON: /api/errors/ff0b6a15964065f8.
Report an issue: GitHub.