rwf2/Rocket · critical · io::Error

error reading TLS file `{source}`: {e}

Error message

error reading TLS file `{source}`: {e}

What it means

Configuration/startup error from Rocket's TLS setup (core/lib/src/tls/config.rs): while converting the configured certs/keys value into a reader, opening the configured file path failed; the io error is re-wrapped with a message naming the figment Source::File path ('error reading TLS file `path`: e'). This surfaces during server ignition when TLS is configured via Rocket.toml ([tls] certs/key/muts), and the underlying io::Error kind (NotFound, PermissionDenied, ...) is preserved.

Source

Thrown at core/lib/src/tls/config.rs:614

    ];

    /// Used as the `serde` default for `ciphers`.
    fn default_set() -> IndexSet<Self> {
        Self::DEFAULT_SET.iter().copied().collect()
    }
}

pub(crate) fn to_reader(
    value: &Either<RelativePathBuf, Vec<u8>>
) -> io::Result<Box<dyn io::BufRead + Sync + Send>> {
    match value {
        Either::Left(path) => {
            let path = path.relative();
            let file = std::fs::File::open(&path)
                .map_err(move |e| {
                    let source = figment::Source::File(path);
                    let msg = format!("error reading TLS file `{source}`: {e}");
                    io::Error::new(e.kind(), msg)
                })?;

            Ok(Box::new(io::BufReader::new(file)))
        }
        Either::Right(vec) => Ok(Box::new(io::Cursor::new(vec.clone()))),
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use figment::{Figment, providers::{Toml, Format}};

    #[test]
    fn test_tls_config_from_file() {
        use crate::tls::{TlsConfig, CipherSuite};
        use pretty_assertions::assert_eq;

View on GitHub (pinned to 3a54d079ae)

Solutions

  1. Run the binary from the directory the TLS paths are relative to, or use absolute paths in Rocket.toml
  2. Verify existence and permission as the service user: sudo -u app cat /etc/app/certs.pem
  3. In containers, double-check the mount target matches the configured path exactly
  4. If certs rotate, ensure the new file replaces the path atomically and restart the service

Example fix

# before
# Rocket.toml
[default.tls]
certs = "certs.pem"   # run from another dir → NotFound
key = "key.pem"

# after
[default.tls]
certs = "/etc/myapp/certs.pem"
key = "/etc/myapp/key.pem"
# $ sudo -u myapp cat /etc/myapp/key.pem  # must succeed
Defensive patterns

Strategy: validation

Validate before calling

// at startup, verify TLS files exist and are readable before ignite
fn tls_files_ok(certs: &str, key: &str) -> io::Result<()> {
    for p in [certs, key] {
        let path = std::path::Path::new(p);
        if !path.is_absolute() { /* relative to CWD: verify CWD matches deployment */ }
        std::fs::File::open(path)?; // fails with NotFound/PermissionDenied early
    }
    Ok(())
}

Try / catch

match rocket::custom(figment).launch().await {
    Err(e) if e.to_string().contains("error reading TLS file") => {
        eprintln!("TLS config broken — check cert/key paths and permissions: {e}");
        std::process::exit(2);
    }
    other => { let _ = other?; }
}

Prevention

When it happens

Trigger: Rocket.toml has [default.tls] certs = "certs.pem" key = "key.pem", and the relative path doesn't resolve from the binary's working directory at launch, the file is missing, or the process lacks read permission. Also triggers when paths are correct in CI but wrong in the container, or when key files are mounted with root-only permissions.

Common situations: Running the binary from a different CWD than during development (relative TLS paths silently break); Docker volumes mounting certs at another path; cert-manager renewal renaming files; systemd services with ProtectHome= making paths unreadable.

Understand the failure class

Related errors


AI-assisted analysis of rwf2/Rocket@3a54d079ae (2026-08-16). Data as JSON: /api/errors/d7c8f353fba43caf. Report an issue: GitHub.