{"record":{"id":"d2b952a39367b3a8","repo":"coollabsio/coolify","slug":"failed-to-write-ssh-key-to-filesystem-check-disk","errorCode":null,"errorMessage":"Failed to write SSH key to filesystem. Check disk space and permissions for: {$keyLocation}","messagePattern":"Failed to write SSH key to filesystem\\. Check disk space and permissions for: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"app/Models/PrivateKey.php","lineNumber":229,"sourceCode":"        // Ensure the storage directory exists and is writable\n        $this->ensureStorageDirectoryExists();\n\n        // Use file locking to prevent concurrent writes from corrupting the key\n        $lockHandle = fopen($lockFile, 'c');\n        if ($lockHandle === false) {\n            throw new \\Exception(\"Failed to open lock file for SSH key: {$lockFile}\");\n        }\n\n        try {\n            if (! flock($lockHandle, LOCK_EX)) {\n                throw new \\Exception(\"Failed to acquire lock for SSH key: {$keyLocation}\");\n            }\n\n            // Attempt to store the private key\n            $success = $disk->put($filename, $this->private_key);\n\n            if (! $success) {\n                throw new \\Exception(\"Failed to write SSH key to filesystem. Check disk space and permissions for: {$keyLocation}\");\n            }\n\n            // Verify the file was actually created and has content\n            if (! $disk->exists($filename)) {\n                throw new \\Exception(\"SSH key file was not created: {$keyLocation}\");\n            }\n\n            $storedContent = $disk->get($filename);\n            if (empty($storedContent) || $storedContent !== $this->private_key) {\n                $disk->delete($filename); // Clean up the bad file\n                throw new \\Exception(\"SSH key file content verification failed: {$keyLocation}\");\n            }\n\n            // Ensure correct permissions for SSH (0600 required)\n            if (file_exists($keyLocation) && ! chmod($keyLocation, 0600)) {\n                Log::warning('Failed to set SSH key file permissions to 0600', [\n                    'key_uuid' => $this->uuid,\n                    'path' => $keyLocation,","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Models/PrivateKey.php#L211-L247","documentation":"Thrown by PrivateKey::storeInFileSystem() (app/Models/PrivateKey.php:229). With the lock held, $disk->put(\"ssh_key@{uuid}\", $this->private_key) on the 'ssh-keys' disk returned false — Laravel's local driver returns false when file_put_contents fails, i.e. the write never hit disk. Combined with the preceding ensureStorageDirectoryExists() test write, this points to disk space exhaustion or a permission/ownership change that happened between the test write and the real write.","triggerScenarios":"Creating or updating an SSH key when the host volume holding /data/coolify/ssh is full (ENOSPC) or became unwritable mid-operation (ownership flipped, quota hit, read-only remount on IO error).","commonSituations":"Full host disk from Docker images/logs; LVM/quota limits on the data volume; filesystem auto-remounted read-only after an error; multi-worker writes racing a permissions fix.","solutions":["Free space on the host (docker system prune, log rotation) and retry — the transaction and lock cleanup leave no partial state.","Re-apply the ownership fix: sudo chown -R 9999 /data/coolify/ssh && sudo chmod -R 700 /data/coolify/ssh && docker restart coolify.","dmesg/df -h the host to rule out a read-only remount or quota.","The earlier create/update that failed rolls back (createAndStore wraps this in DB::transaction()), so simply retry after fixing."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight free space on the storage backing the ssh-keys disk\n$path = Storage::disk('ssh-keys')->path('');\nif (disk_free_space($path) === false || disk_free_space($path) < 1024) {\n    throw new \\RuntimeException('Insufficient disk space for SSH key storage.');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $privateKey->storeInFileSystem();\n} catch (\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Check disk space and permissions')) {\n        // free space / fix ownership, then retry — no partial file is left\n    }\n    throw $e;\n}","preventionTips":["Alert on host disk usage; key writes fail at 100% but so does everything else on the volume.","After any permission change on /data/coolify/ssh, re-run the chown 9999 + chmod 700 + restart sequence."],"tags":["coolify","ssh-key","disk-space","file-storage","permissions"],"backgroundTag":"disk-space-exhausted","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}