{"record":{"id":"a112dc87c9851c38","repo":"coollabsio/coolify","slug":"failed-to-store-ssh-key-message","errorCode":null,"errorMessage":"Failed to store SSH key: {message}","messagePattern":"Failed to store SSH key: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"app/Models/PrivateKey.php","lineNumber":155,"sourceCode":"        try {\n            PublicKeyLoader::load($privateKey);\n\n            return true;\n        } catch (\\Throwable $e) {\n            return false;\n        }\n    }\n\n    public static function createAndStore(array $data)\n    {\n        return DB::transaction(function () use ($data) {\n            $privateKey = new self($data);\n            $privateKey->save();\n\n            try {\n                $privateKey->storeInFileSystem();\n            } catch (\\Exception $e) {\n                throw new \\Exception('Failed to store SSH key: '.$e->getMessage());\n            }\n\n            return $privateKey;\n        });\n    }\n\n    public static function generateNewKeyPair($type = 'rsa')\n    {\n        try {\n            $instance = new self;\n            $instance->rateLimit(10);\n            $name = generate_random_name();\n            $description = 'Created by Coolify';\n            $keyPair = generateSSHKey($type === 'ed25519' ? 'ed25519' : 'rsa');\n\n            return [\n                'name' => $name,\n                'description' => $description,","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Models/PrivateKey.php#L137-L173","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\n$privateKey = PrivateKey::createAndStore($request->validated()); // throws, row rolled back\n\n// after — surface the underlying storage error to the operator\ntry {\n    $privateKey = PrivateKey::createAndStore($data);\n} catch (\\Exception $e) {\n    // $e->getMessage() contains the storeInFileSystem() cause (permissions, disk, lock)\n    return back()->withErrors(['private_key' => $e->getMessage()]);\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight the SSH key storage before creating a key\n$disk = Storage::disk('ssh-keys');\n$probe = '.preflight_'.uniqid();\nif (! $disk->put($probe, 'ok') || $disk->get($probe) !== 'ok') {\n    throw new \\RuntimeException('SSH key storage not writable — fix /data/coolify/ssh ownership first.');\n}\n$disk->delete($probe);","typeGuard":null,"tryCatchPattern":"try {\n    $privateKey = PrivateKey::createAndStore($data);\n} catch (\\Exception $e) {\n    // Message embeds the storeInFileSystem() cause (permissions / disk / lock)\n    return back()->withErrors(['private_key' => $e->getMessage()]);\n}","preventionTips":["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."],"tags":["coolify","ssh-key","file-storage","transactions","permissions"],"backgroundTag":"file-write-permission-denied","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}