{"record":{"id":"d7a71855bcfb2b5e","repo":"coollabsio/coolify","slug":"failed-to-open-lock-file-for-ssh-key-lockfile","errorCode":null,"errorMessage":"Failed to open lock file for SSH key: {$lockFile}","messagePattern":"Failed to open lock file for SSH key: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"app/Models/PrivateKey.php","lineNumber":217,"sourceCode":"            'isValid' => $isValid,\n            'publicKey' => $publicKey,\n        ];\n    }\n\n    public function storeInFileSystem()\n    {\n        $filename = \"ssh_key@{$this->uuid}\";\n        $disk = Storage::disk('ssh-keys');\n        $keyLocation = $this->getKeyLocation();\n        $lockFile = $keyLocation.'.lock';\n\n        // 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            }","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Models/PrivateKey.php#L199-L235","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight: can the process create a file next to the key location?\n$dir = dirname($privateKey->getKeyLocation());\nif (! is_dir($dir) || ! is_writable($dir)) {\n    throw new \\RuntimeException(\"SSH storage dir not writable: {$dir}\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    $privateKey->storeInFileSystem();\n} catch (\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Failed to open lock file')) {\n        // ownership/open_basedir problem on /data/coolify/ssh — fix and retry\n    }\n    throw $e;\n}","preventionTips":["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."],"tags":["coolify","ssh-key","file-storage","permissions","file-locking"],"backgroundTag":"file-write-permission-denied","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}