astrid-runtime/astrid · error

tls.cert-path and tls.key-path resolve to the same file

Error message

tls.cert-path and tls.key-path resolve to the same file ({}); separate them

What it means

Defensive check in GatewayConfig::validate: tls.cert-path and tls.key-path resolve to the same file — the classic copy-paste typo of pointing both at the certificate — which would make TLS unusable at handshake time.

Solutions

  1. Point tls.key-path at the private-key PEM and tls.cert-path at the certificate PEM — two different files
  2. If only one file exists, regenerate or export the missing half of the keypair
  3. Re-check the config after templating/secret injection that may have collapsed both values
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/astrid-gateway/src/config.rs:169 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/ca7f29cb9a170a64. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-gateway/src/config.rs:169

            // clear error.
            if !tls.cert_path.is_file() {
                anyhow::bail!(
                    "tls.cert-path {} is not a regular file — refusing to boot the gateway",
                    tls.cert_path.display()
                );
            }
            if !tls.key_path.is_file() {
                anyhow::bail!(
                    "tls.key-path {} is not a regular file — refusing to boot the gateway",
                    tls.key_path.display()
                );
            }
            // Defensive: catch the copy-paste typo where cert+key
            // point at the same file. The rustls PEM parser will
            // happily try to load a private key out of the cert chain
            // and produce a cryptic error; surface the problem here.
            if tls.cert_path == tls.key_path {
                anyhow::bail!(
                    "tls.cert-path and tls.key-path resolve to the same file ({}); separate them",
                    tls.cert_path.display()
                );
            }
            crate::tls::warn_if_key_is_too_open(&tls.key_path);
        }
        Ok(())
    }
}

/// Validate a single CORS origin string. Origins MUST be of the form
/// `scheme://host[:port]` with no path, query, or fragment — that's
/// what the browser sends in `Origin:` and what the response's
/// `Access-Control-Allow-Origin:` is byte-matched against. A
/// `https://app.example/` (trailing slash) would silently fail to
/// match a real preflight; rejecting it here is what makes that
/// surfacable.
fn validate_cors_origin(raw: &str) -> anyhow::Result<()> {

View on GitHub (pinned to affd8760f4)