{"record":{"id":"42d328e96b4d81cd","repo":"astrid-runtime/astrid","slug":"tls-cert-path-is-not-a-regular-file-refusing","errorCode":null,"errorMessage":"tls.cert-path {} is not a regular file — refusing to boot the gateway","messagePattern":"tls\\.cert-path (.+?) is not a regular file — refusing to boot the gateway","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-gateway/src/config.rs","lineNumber":153,"sourceCode":"    /// * **CORS origins** are checked against the `scheme://host[:port]`\n    ///   shape so an operator who typoed a trailing slash, fragment,\n    ///   IDN, etc., fails boot with a clear message rather than\n    ///   silently never matching a browser preflight.\n    /// * **TLS** cert/key paths must exist as regular files and not\n    ///   collide with each other — both common misconfigurations\n    ///   that the rustls PEM parser would surface as bewildering\n    ///   downstream errors.\n    pub fn validate(&self) -> anyhow::Result<()> {\n        for raw in &self.cors_allow_origins {\n            validate_cors_origin(raw)?;\n        }\n        if let Some(tls) = &self.tls {\n            // `is_file()` catches both \"doesn't exist\" and \"points\n            // at a directory\". `exists()` alone would pass for a\n            // directory and fail later inside rustls with a less\n            // clear error.\n            if !tls.cert_path.is_file() {\n                anyhow::bail!(\n                    \"tls.cert-path {} is not a regular file — refusing to boot the gateway\",\n                    tls.cert_path.display()\n                );\n            }\n            if !tls.key_path.is_file() {\n                anyhow::bail!(\n                    \"tls.key-path {} is not a regular file — refusing to boot the gateway\",\n                    tls.key_path.display()\n                );\n            }\n            // Defensive: catch the copy-paste typo where cert+key\n            // point at the same file. The rustls PEM parser will\n            // happily try to load a private key out of the cert chain\n            // and produce a cryptic error; surface the problem here.\n            if tls.cert_path == tls.key_path {\n                anyhow::bail!(\n                    \"tls.cert-path and tls.key-path resolve to the same file ({}); separate them\",\n                    tls.cert_path.display()","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-gateway/src/config.rs#L135-L171","documentation":"Boot-time config validation in GatewayConfig::validate: tls.cert-path either does not exist or points at a directory; is_file() catches both, refusing to boot rather than failing later inside the rustls PEM parser with an obscure error.","triggerScenarios":"Thrown at crates/astrid-gateway/src/config.rs:153 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Correct the tls.cert-path in the gateway config to point at the PEM certificate file","Verify the path exists and is a regular file, not a directory","Copy or mount the certificate to the expected location if it is missing"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}