oven-sh/bun · error

Failed to generate SSH key: ${privatePath} / ${publicPath}

Error message

Failed to generate SSH key: ${privatePath} / ${publicPath}

What it means

createSshKey() locates ssh-keygen via `which(required:true)`, runs `ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_<uuid> -N ''` with inherited stdio, then requires both the private and .pub files to exist. The throw means ssh-keygen ran but produced no key files (its real error was printed to your terminal by the inherited stdio).

Source

Thrown at scripts/machine.mjs:851

 * @property {string} publicKey
 */

/**
 * @returns {SshKey}
 */
function createSshKey() {
  const sshKeyGen = which("ssh-keygen", { required: true });
  const sshAdd = which("ssh-add", { required: true });

  const sshPath = join(homedir(), ".ssh");
  mkdir(sshPath);

  const filename = `id_rsa_${crypto.randomUUID()}`;
  const privatePath = join(sshPath, filename);
  const publicPath = join(sshPath, `${filename}.pub`);
  spawnSyncSafe([sshKeyGen, "-t", "rsa", "-b", "4096", "-f", privatePath, "-N", ""], { stdio: "inherit" });
  if (!existsSync(privatePath) || !existsSync(publicPath)) {
    throw new Error(`Failed to generate SSH key: ${privatePath} / ${publicPath}`);
  }

  if (isWindows) {
    spawnSyncSafe([sshAdd, privatePath], { stdio: "inherit" });
  } else {
    const sshAgent = which("ssh-agent");
    if (sshAgent) {
      spawnSyncSafe(["sh", "-c", `eval $(${sshAgent} -s) && ${sshAdd} ${privatePath}`], { stdio: "inherit" });
    }
  }

  return {
    privatePath,
    publicPath,
    get publicKey() {
      return readFile(publicPath, { cache: true });
    },
  };

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Reproduce manually: `ssh-keygen -t rsa -b 4096 -f ~/.ssh/testkey -N ''`
  2. Check `echo $HOME`, ensure ~/.ssh exists and is writable (mkdir is already attempted — look for its failure)
  3. Inspect the ssh-keygen stderr that was printed with stdio: 'inherit' just before the throw
  4. Free disk space / fix permissions on the home directory
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the prerequisites createSshKey assumes
if (!existsSync(join(homedir(), '.ssh'))) {
  throw new Error(`~/.ssh missing and HOME=${homedir()} may be wrong for this container`);
}
Bun.spawnSync(['ssh-keygen', '--help'], { stdout: 'ignore', stderr: 'ignore' });

Try / catch

try {
  sshKeys = createSshKey();
} catch (error) {
  // The inherited stdio already printed ssh-keygen's reason; surface HOME context
  throw new Error(`SSH key generation failed (HOME=${homedir()}): ${error}`);
}

Prevention

When it happens

Trigger: ~/.ssh (from homedir()) not writable or HOME unset/odd in a CI container; ssh-keygen exiting non-zero (disk full, unsupported options, permission denied on the output path) while spawnSyncSafe continues; path length or filesystem issues on Windows.

Common situations: CI container running with a read-only or missing home; HOME pointing somewhere unexpected; corporate antivirus locking the file on Windows.

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/407497790d0647f4. Report an issue: GitHub.