EpicGames/lore · error
failed to write ephemeral certificate
Error message
failed to write ephemeral certificate {}: {e} What it means
After generating the ephemeral key pair, generate_ephemeral_certificate writes the PEM certificate to a file under <tmp>/lore-server with std::fs::write, mapping any IO error to this message with the full file path and OS error. The endpoint setup later reads this file, so a failed write aborts startup. Failures here mean the directory was creatable but the file write itself failed.
Solutions
- Inspect the OS error: free disk space if 'No space left', or fix ownership of the existing cert file / /tmp/lore-server directory.
- Clear stale ephemeral artifacts: remove old cert/key files under <tmp>/lore-server so the new write succeeds.
- Run under a user that owns the temp directory, or point TMPDIR to a writable dedicated location.
- Provide explicit certificate configuration to bypass the ephemeral path entirely.
Defensive patterns
Strategy: try-catch
Validate before calling
// Rust, preflight write test
let probe = dir.join(".write-probe");
std::fs::write(&probe, b"ok").map_err(|e| format!("{} not writable: {e}", dir.display()))?;
let _ = std::fs::remove_file(&probe); Try / catch
match std::fs::write(&cert_file, &generated.cert_pem) {
Ok(()) => {},
Err(e) => {
eprintln!("cannot write {}: {e}; check ownership of {} and free disk space", cert_file.display(), dir.display());
return Err(anyhow::Error::new(e).context(format!("ephemeral cert write failed: {}", cert_file.display())));
}
} Prevention
- After switching run users (root→app user), chown /tmp/lore-server or delete stale artifacts.
- Monitor free space/quota on the volume backing TMPDIR.
- Pin one server instance per machine temp dir; avoid concurrent instances sharing artifact names.
- Prefer explicit certificate configuration to avoid ephemeral writes in production.
When it happens
Trigger: std::fs::write(&cert_file, generated.cert_pem) fails — the target path exists as a directory, the file is owned by another user (from a previous root-run), the filesystem is full, or AV/security policy blocks writes there.
Common situations: Stale artifacts in /tmp/lore-server owned by root after switching the service to a non-root user; disk quota/full /tmp on a small container; SELinux/AppArmor denying writes to the temp path.
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.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to write ephemeral private key
- failed to create directory
- gRPC internal TLS is partially configured: cert=
- TLS is partially configured: cert_file and pkey_file must…
- Maintenance TLS is partially configured: cert_file and…
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/46c9d703ee79da51.
Report an issue: GitHub.
Appendix: source
Thrown at lore-server/src/server.rs:1087
std::fs::create_dir_all(&dir).map_err(|e| {
anyhow!(
"failed to create directory {} for ephemeral certificate: {e}",
dir.display()
)
})?;
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."View on GitHub (pinned to 074eb0b0d1)