{"record":{"id":"d7c8f353fba43caf","repo":"rwf2/Rocket","slug":"error-reading-tls-file-source-e","errorCode":null,"errorMessage":"error reading TLS file `{source}`: {e}","messagePattern":"error reading TLS file `(.+?)`: (.+?)","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"critical","filePath":"core/lib/src/tls/config.rs","lineNumber":614,"sourceCode":"    ];\n\n    /// Used as the `serde` default for `ciphers`.\n    fn default_set() -> IndexSet<Self> {\n        Self::DEFAULT_SET.iter().copied().collect()\n    }\n}\n\npub(crate) fn to_reader(\n    value: &Either<RelativePathBuf, Vec<u8>>\n) -> io::Result<Box<dyn io::BufRead + Sync + Send>> {\n    match value {\n        Either::Left(path) => {\n            let path = path.relative();\n            let file = std::fs::File::open(&path)\n                .map_err(move |e| {\n                    let source = figment::Source::File(path);\n                    let msg = format!(\"error reading TLS file `{source}`: {e}\");\n                    io::Error::new(e.kind(), msg)\n                })?;\n\n            Ok(Box::new(io::BufReader::new(file)))\n        }\n        Either::Right(vec) => Ok(Box::new(io::Cursor::new(vec.clone()))),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use figment::{Figment, providers::{Toml, Format}};\n\n    #[test]\n    fn test_tls_config_from_file() {\n        use crate::tls::{TlsConfig, CipherSuite};\n        use pretty_assertions::assert_eq;\n","sourceCodeStart":596,"sourceCodeEnd":632,"githubUrl":"https://github.com/rwf2/Rocket/blob/3a54d079aef060a8f732bd04ea54b0581a604087/core/lib/src/tls/config.rs#L596-L632","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run the binary from the directory the TLS paths are relative to, or use absolute paths in Rocket.toml","Verify existence and permission as the service user: sudo -u app cat /etc/app/certs.pem","In containers, double-check the mount target matches the configured path exactly","If certs rotate, ensure the new file replaces the path atomically and restart the service"],"exampleFix":"# before\n# Rocket.toml\n[default.tls]\ncerts = \"certs.pem\"   # run from another dir → NotFound\nkey = \"key.pem\"\n\n# after\n[default.tls]\ncerts = \"/etc/myapp/certs.pem\"\nkey = \"/etc/myapp/key.pem\"\n# $ sudo -u myapp cat /etc/myapp/key.pem  # must succeed","handlingStrategy":"validation","validationCode":"// at startup, verify TLS files exist and are readable before ignite\nfn tls_files_ok(certs: &str, key: &str) -> io::Result<()> {\n    for p in [certs, key] {\n        let path = std::path::Path::new(p);\n        if !path.is_absolute() { /* relative to CWD: verify CWD matches deployment */ }\n        std::fs::File::open(path)?; // fails with NotFound/PermissionDenied early\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match rocket::custom(figment).launch().await {\n    Err(e) if e.to_string().contains(\"error reading TLS file\") => {\n        eprintln!(\"TLS config broken — check cert/key paths and permissions: {e}\");\n        std::process::exit(2);\n    }\n    other => { let _ = other?; }\n}","preventionTips":["Use absolute TLS paths in production configs","Add a pre-launch readiness check (or entrypoint script) that cats both files as the service user","Pin cert file names across renewals (atomic replace, same path) so config never goes stale"],"tags":["rust","rocket","tls","configuration","startup","certificates"],"backgroundTag":"tls-certificate-file-not-found","analyzedSha":"3a54d079aef060a8f732bd04ea54b0581a604087","analyzedAt":"2026-08-16T22:01:48.395Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}