coollabsio/coolify · error · Exception
Failed to open lock file for SSH key: {$lockFile}
Error message
Failed to open lock file for SSH key: {$lockFile} What it means
Thrown by PrivateKey::storeInFileSystem() (app/Models/PrivateKey.php:217). Before writing ssh_key@{uuid}, the routine opens a sibling lock file ({keyLocation}.lock) with fopen($lockFile, 'c') to serialize concurrent writes. ensureStorageDirectoryExists() has already run at this point, so a false return means the OS refused to create/open the lock file itself — almost always a permission or path-level denial on the 'ssh-keys' disk (root /data/coolify/ssh), e.g. open_basedir restrictions, SELinux denial, or a read-only mount.
Source
Thrown at app/Models/PrivateKey.php:217
'isValid' => $isValid,
'publicKey' => $publicKey,
];
}
public function storeInFileSystem()
{
$filename = "ssh_key@{$this->uuid}";
$disk = Storage::disk('ssh-keys');
$keyLocation = $this->getKeyLocation();
$lockFile = $keyLocation.'.lock';
// Ensure the storage directory exists and is writable
$this->ensureStorageDirectoryExists();
// Use file locking to prevent concurrent writes from corrupting the key
$lockHandle = fopen($lockFile, 'c');
if ($lockHandle === false) {
throw new \Exception("Failed to open lock file for SSH key: {$lockFile}");
}
try {
if (! flock($lockHandle, LOCK_EX)) {
throw new \Exception("Failed to acquire lock for SSH key: {$keyLocation}");
}
// Attempt to store the private key
$success = $disk->put($filename, $this->private_key);
if (! $success) {
throw new \Exception("Failed to write SSH key to filesystem. Check disk space and permissions for: {$keyLocation}");
}
// Verify the file was actually created and has content
if (! $disk->exists($filename)) {
throw new \Exception("SSH key file was not created: {$keyLocation}");
}View on GitHub (pinned to 70b9acc424)
Solutions
- On the host run: sudo chown -R 9999 /data/coolify/ssh && sudo chmod -R 700 /data/coolify/ssh && docker restart coolify.
- Confirm the mount is writable: docker exec coolify touch /data/coolify/ssh/.wtest.
- Check open_basedir/SELinux denials in PHP-FPM and host audit logs if ownership looks correct.
- Retry the key save once write access is confirmed.
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: can the process create a file next to the key location?
$dir = dirname($privateKey->getKeyLocation());
if (! is_dir($dir) || ! is_writable($dir)) {
throw new \RuntimeException("SSH storage dir not writable: {$dir}");
} Try / catch
try {
$privateKey->storeInFileSystem();
} catch (\Exception $e) {
if (str_contains($e->getMessage(), 'Failed to open lock file')) {
// ownership/open_basedir problem on /data/coolify/ssh — fix and retry
}
throw $e;
} Prevention
- Keep /data/coolify/ssh owned by 9999:700 and never mount it read-only.
- If PHP hardening (open_basedir) is in play, include the ssh-keys root in the allowed paths.
When it happens
Trigger: Saving/creating/updating a PrivateKey while the Coolify process (uid 9999) cannot create files in the ssh-keys storage root — directory exists but is owned by root with no write bit, is mounted read-only, or PHP open_basedir excludes the path.
Common situations: Host permission drift on /data/coolify/ssh after host OS upgrades or restores; hardened PHP configs with open_basedir; containers started with a :ro bind mount for the data volume.
Related errors
- Failed to store SSH key: {message}
- Failed to acquire lock for SSH key: {$keyLocation}
- Failed to write SSH key to filesystem. Check disk space and
- Failed to create SSH keys storage directory
- SSH keys storage directory is not writable. Run on the host:
AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17).
Data as JSON: /api/errors/d7a71855bcfb2b5e.
Report an issue: GitHub.