coollabsio/coolify · error · Exception
Failed to generate new {$type} key: {message}
Error message
Failed to generate new {$type} key: {message} What it means
Thrown by PrivateKey::generateNewKeyPair() (app/Models/PrivateKey.php:178). This static helper rate-limits itself ($instance->rateLimit(10)), maps the requested type to 'ed25519' or 'rsa', then shells out via generateSSHKey($type). Any Throwable — a rate-limit exception, a missing ssh-keygen binary, or a process error — is caught and re-wrapped as "Failed to generate new {$type} key: {message}". Note the rate limiter (10 attempts) throws TooManyAttemptsException, which is a Throwable, so hitting the limit also surfaces through this message with a misleading 'key generation' framing.
Source
Thrown at app/Models/PrivateKey.php:178
}
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,
'private_key' => $keyPair['private'],
'public_key' => $keyPair['public'],
];
} catch (\Throwable $e) {
throw new \Exception("Failed to generate new {$type} key: ".$e->getMessage());
}
}
public static function extractPublicKeyFromPrivate($privateKey)
{
try {
$key = PublicKeyLoader::load($privateKey);
return $key->getPublicKey()->toString('OpenSSH', ['comment' => '']);
} catch (\Throwable $e) {
return null;
}
}
public static function validateAndExtractPublicKey($privateKey)
{
$isValid = self::validatePrivateKey($privateKey);
$publicKey = $isValid ? self::extractPublicKeyFromPrivate($privateKey) : '';View on GitHub (pinned to 70b9acc424)
Solutions
- If you generated several keys recently, wait for the rate-limit window to decay (limit is 10) and retry.
- Verify ssh-keygen exists in the container: docker exec coolify which ssh-keygen.
- Check the appended {message} — it distinguishes 'Too many attempts' from an ssh-keygen/exec failure.
- Only pass 'rsa' or 'ed25519'; other values are silently coerced to rsa but the message will echo your original $type.
Example fix
// before
for ($i = 0; $i < 15; $i++) {
$pair = PrivateKey::generateNewKeyPair('ed25519'); // trips 10/attempt limit
}
// after — pace generation or use RateLimiter::tooManyAttempts to precheck
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::tooManyAttempts('generate-key:'.auth()->id(), 10)) {
return back()->withErrors(['key' => 'Slow down — key generation is rate limited.']);
}
$pair = PrivateKey::generateNewKeyPair('ed25519'); Defensive patterns
Strategy: retry
Validate before calling
// Pre-check the rate limit used by generateNewKeyPair
use Illuminate\Support\Facades\RateLimiter;
$key = 'generate-key:'.(auth()->id() ?? 'system');
if (RateLimiter::tooManyAttempts($key, 10)) {
$seconds = RateLimiter::availableIn($key);
abort(429, "Key generation rate limited. Retry in {$seconds}s.");
} Try / catch
try {
$pair = PrivateKey::generateNewKeyPair('ed25519');
} catch (\Exception $e) {
if (str_contains($e->getMessage(), 'Too Many Attempts')) {
// back off and retry after RateLimiter::availableIn()
return retry(after: fn () => RateLimiter::availableIn($key), callback: fn () => PrivateKey::generateNewKeyPair('ed25519'));
}
throw $e; // ssh-keygen/exec failure — check binary availability
} Prevention
- Batch key generation with pacing; the limiter is 10 attempts per window per instance model.
- Confirm ssh-keygen exists in the image before shipping custom Coolify containers.
- Read the appended {message} to distinguish rate limiting from a missing binary.
When it happens
Trigger: Calling PrivateKey::generateNewKeyPair('ed25519') or ('rsa') more than 10 times in a short window (rate limit), or when ssh-keygen is absent/broken in the Coolify container, or the temp area used by generateSSHKey() is not writable.
Common situations: UI/script generating many key pairs in a loop (e.g. seeding servers) and tripping the 10-per-window limiter; slim/custom Coolify images without openssh-client; read-only /tmp inside the container.
Related errors
- Failed to store SSH key: {message}
- Failed to open lock file for SSH key: {$lockFile}
- Failed to acquire lock for SSH key: {$keyLocation}
- Failed to write SSH key to filesystem. Check disk space and
- SSH key file was not created: {$keyLocation}
AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17).
Data as JSON: /api/errors/d133031e02b6b96f.
Report an issue: GitHub.