coollabsio/coolify · error · Exception
Failed to store SSH key: {message}
Error message
Failed to store SSH key: {message} What it means
Thrown by PrivateKey::createAndStore() (app/Models/PrivateKey.php:155). The whole create-and-store runs inside DB::transaction(): the model row is saved, then storeInFileSystem() writes the key to the 'ssh-keys' disk under ssh_key@{uuid} with lock-file protection, content verification, and chmod 0600. If any part of that filesystem routine throws, the exception is wrapped as 'Failed to store SSH key: {message}' and the DB transaction rolls back the model row. The {message} suffix carries the specific underlying failure (one of errors 309–315).
Source
Thrown at app/Models/PrivateKey.php:155
try {
PublicKeyLoader::load($privateKey);
return true;
} catch (\Throwable $e) {
return false;
}
}
public static function createAndStore(array $data)
{
return DB::transaction(function () use ($data) {
$privateKey = new self($data);
$privateKey->save();
try {
$privateKey->storeInFileSystem();
} catch (\Exception $e) {
throw new \Exception('Failed to store SSH key: '.$e->getMessage());
}
return $privateKey;
});
}
public static function generateNewKeyPair($type = 'rsa')
{
try {
$instance = new self;
$instance->rateLimit(10);
$name = generate_random_name();
$description = 'Created by Coolify';
$keyPair = generateSSHKey($type === 'ed25519' ? 'ed25519' : 'rsa');
return [
'name' => $name,
'description' => $description,View on GitHub (pinned to 70b9acc424)
Solutions
- Run the host-side fix printed by the storage guard: sudo chown -R 9999 /data/coolify/ssh && sudo chmod -R 700 /data/coolify/ssh && docker restart coolify.
- Check df -h on the host — a full disk makes disk->put fail.
- Retry the key creation; the failed model row was rolled back, so there is no half-created key.
- If storage is on NFS/a bind mount with odd locking, move the ssh-keys disk to local storage (config/filesystems.php 'ssh-keys' disk root).
Example fix
// before
$privateKey = PrivateKey::createAndStore($request->validated()); // throws, row rolled back
// after — surface the underlying storage error to the operator
try {
$privateKey = PrivateKey::createAndStore($data);
} catch (\Exception $e) {
// $e->getMessage() contains the storeInFileSystem() cause (permissions, disk, lock)
return back()->withErrors(['private_key' => $e->getMessage()]);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight the SSH key storage before creating a key
$disk = Storage::disk('ssh-keys');
$probe = '.preflight_'.uniqid();
if (! $disk->put($probe, 'ok') || $disk->get($probe) !== 'ok') {
throw new \RuntimeException('SSH key storage not writable — fix /data/coolify/ssh ownership first.');
}
$disk->delete($probe); Try / catch
try {
$privateKey = PrivateKey::createAndStore($data);
} catch (\Exception $e) {
// Message embeds the storeInFileSystem() cause (permissions / disk / lock)
return back()->withErrors(['private_key' => $e->getMessage()]);
} Prevention
- Right after install, verify uid 9999 owns /data/coolify/ssh before adding any keys.
- Monitor host disk space — key writes are small but put() fails hard on ENOSPC.
- Rely on the DB transaction: a failed createAndStore leaves no model row, so a plain retry is safe after fixing storage.
When it happens
Trigger: PrivateKey::createAndStore([...]) when the Coolify container cannot write to the SSH key storage: missing/unwritable directory (ensureStorageDirectoryExists failure), fopen/flock lock-file failure, disk->put returning false, or write verification mismatch — typically a permissions or disk-space problem on /data/coolify/ssh.
Common situations: Fresh installs where /data/coolify/ssh is owned by root instead of uid 9999; host volume permission drift after a Docker upgrade; disk full on the host; NFS-backed storage where flock or fsync semantics differ.
Related errors
- Failed to open lock file for SSH key: {$lockFile}
- 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:
- Failed to acquire lock for SSH key: {$keyLocation}
AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17).
Data as JSON: /api/errors/a112dc87c9851c38.
Report an issue: GitHub.