Unitech/pm2 · error · Error
Could not create folder
Error message
Could not create folder
What it means
When PM2 resolves out_file / error_file / log file paths for an app, it ensures the parent directory exists by calling fs.mkdirSync(dir, {recursive:true}). If that call throws (permission denied, read-only filesystem, invalid path, disk full), the error is surfaced as 'Could not create folder'.
Source
Thrown at lib/Common.js:220
['log', 'out', 'error', 'pid'].forEach(function(f){
var af = app[f + '_file'], ps, ext = (f == 'pid' ? 'pid':'log'), isStd = !~['log', 'pid'].indexOf(f);
if (af) af = resolveHome(af);
if ((f == 'log' && typeof af == 'boolean' && af) || (f != 'log' && !af)) {
ps = [cst['DEFAULT_' + ext.toUpperCase() + '_PATH'], formated_app_name + (isStd ? '-' + f : '') + '.' + ext];
} else if ((f != 'log' || (f == 'log' && af)) && af !== 'NULL' && af !== '/dev/null') {
ps = [cwd, af];
var dir = path.dirname(path.resolve(cwd, af));
if (!fs.existsSync(dir)) {
Common.printError(cst.PREFIX_MSG_WARNING + 'Folder does not exist: ' + dir);
Common.printOut(cst.PREFIX_MSG + 'Creating folder: ' + dir);
try {
fs.mkdirSync(dir, { recursive: true });
} catch (err) {
Common.printError(cst.PREFIX_MSG_ERR + 'Could not create folder: ' + path.dirname(af));
throw new Error('Could not create folder');
}
}
}
// PM2 paths
if (af !== 'NULL' && af !== '/dev/null') {
ps && (app['pm_' + (isStd ? f.substr(0, 3) + '_' : '') + ext + '_path'] = path.resolve.apply(null, ps));
} else if (path.sep === '\\') {
app['pm_' + (isStd ? f.substr(0, 3) + '_' : '') + ext + '_path'] = '\\\\.\\NUL';
} else {
app['pm_' + (isStd ? f.substr(0, 3) + '_' : '') + ext + '_path'] = '/dev/null';
}
delete app[f + '_file'];
});
return app;
};
View on GitHub (pinned to 31adee8048)
Solutions
- Point log paths to a directory the PM2 daemon user can write to.
- Pre-create the log directory and grant write access to the daemon user.
- Drop the out_file/error_file overrides so PM2 uses its default log location under PM2_HOME.
Example fix
// before out_file: '/var/log/myapp/out.log' // after out_file: '/home/app/logs/out.log'
Defensive patterns
Strategy: try-catch
Validate before calling
const fs = require('fs');
const path = require('path');
function ensureLogDir(file) {
const dir = path.dirname(path.resolve(file));
try { fs.mkdirSync(dir, { recursive: true }); return true; }
catch (e) { return false; }
}
if (!ensureLogDir(app.out_file) || !ensureLogDir(app.error_file)) {
delete app.out_file; delete app.error_file; // fall back to PM2 defaults
} Try / catch
try {
pm2.start(app, cb);
} catch (e) {
if (/Could not create folder/.test(e.message)) {
delete app.out_file; delete app.error_file;
pm2.start(app, cb);
} else { throw e; }
} Prevention
- Verify the PM2 daemon user can write to every configured log path before start.
- Pre-create log directories in deployment scripts.
- Omit out_file/error_file in production unless you have a writable target dir.
When it happens
Trigger: Configuring an app with out_file/error_file pointing into a directory PM2 cannot create — unwritable location, read-only rootfs, Windows invalid drive, or a path the daemon user can't write to.
Common situations: Apps run as a low-privilege user that logs into /var/log without write permission; containers with a read-only root filesystem; path typos; log dir on an unmounted volume.
AI-assisted analysis of Unitech/pm2@31adee8048 (2026-08-13).
Data as JSON: /api/errors/ae87b8f1de74c47b.
Report an issue: GitHub.