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

  1. 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.
  2. Check df -h on the host — a full disk makes disk->put fail.
  3. Retry the key creation; the failed model row was rolled back, so there is no half-created key.
  4. 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

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


AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17). Data as JSON: /api/errors/a112dc87c9851c38. Report an issue: GitHub.