EpicGames/lore · error

failed to write ephemeral private key

Error message

failed to write ephemeral private key {}: {e}

What it means

Immediately after writing the ephemeral certificate, generate_ephemeral_certificate writes the PEM private key (generated.key_pem) to the key file next to it; an IO failure there is mapped to this error with the key file path and OS error. Startup aborts because the quinn endpoint setup needs both files. Note a partial-write risk: the certificate may already be on disk while the key write fails, leaving mismatched/stale artifacts for the next run.

Solutions

  1. Fix the underlying IO error: free space, correct ownership/permissions on <tmp>/lore-server and the key file.
  2. Delete stale cert+key pairs in <tmp>/lore-server so both files are rewritten consistently by the same process.
  3. Avoid running multiple server instances against one machine temp dir simultaneously, or give each a distinct TMPDIR.
  4. Configure real TLS certificates to stop relying on the ephemeral mechanism.
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust, preflight: ensure both target paths are writable and not directories
for f in [&cert_file, &pkey_file] {
    if f.exists() && f.is_dir() {
        return Err(format!("{} is a directory", f.display()));
    }
}
// verify space for both files
let free = fs4::available_space(&dir)?;
if free < 16_384 { return Err("insufficient space for ephemeral key material".into()); }

Try / catch

let write_pair = || -> anyhow::Result<()> {
    std::fs::write(&cert_file, &generated.cert_pem).context("cert write")?;
    std::fs::write(&pkey_file, &generated.key_pem).context("key write")?;
    Ok(())
};
if let Err(e) = write_pair() {
    // clean up so no mismatched cert/key pair is left behind
    let _ = std::fs::remove_file(&cert_file);
    let _ = std::fs::remove_file(&pkey_file);
    return Err(e);
}

Prevention

When it happens

Trigger: std::fs::write(&pkey_file, generated.key_pem) fails — disk full mid-sequence, key file path occupied by a directory, ownership mismatch on the pre-existing key file, or security policy blocking the write after the cert write succeeded.

Common situations: Small /tmp quota consumed by the just-written cert; another server instance (or a previous root run) owning the key file; race between multiple lore-server instances sharing the same temp dir and trying to write the same key file name.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13). Data as JSON: /api/errors/07b8e2ccb43d904e. Report an issue: GitHub.

Appendix: source

Thrown at lore-server/src/server.rs:1093

    let process_id = std::process::id();
    let cert_file = dir.join(format!("{endpoint}-{process_id}-cert.pem"));
    let pkey_file = dir.join(format!("{endpoint}-{process_id}-key.pem"));

    let generated = lore_transport::tls::generate_self_signed(vec![
        "localhost".to_string(),
        "127.0.0.1".to_string(),
        "::1".to_string(),
    ])?;

    std::fs::write(&cert_file, generated.cert_pem).map_err(|e| {
        anyhow!(
            "failed to write ephemeral certificate {}: {e}",
            cert_file.display()
        )
    })?;
    std::fs::write(&pkey_file, generated.key_pem).map_err(|e| {
        anyhow!(
            "failed to write ephemeral private key {}: {e}",
            pkey_file.display()
        )
    })?;

    warn!(
        endpoint,
        cert = %cert_file.display(),
        key = %pkey_file.display(),
        "No TLS certificate configured for the '{endpoint}' QUIC endpoint; generated an \
         EPHEMERAL SELF-SIGNED certificate. This is untrusted, regenerated on every restart, \
         and intended for local development only. Configure a real certificate for production."
    );

    Ok(crate::tls::CertificateSettings {
        cert_chain: None,
        cert_file,
        pkey_file,

View on GitHub (pinned to 074eb0b0d1)