zeroclaw-labs/zeroclaw · error
client_key is set but client_cert is missing (both are requi
Error message
client_key is set but client_cert is missing (both are required for mutual TLS)
What it means
The mirror of the cert-without-key check: a bare `client_key` with no `client_cert` is an incomplete mTLS identity and is rejected before connect. The validator's `(false, true)` match arm fires only for this shape, so the fix is always to supply the certificate half.
Source
Thrown at crates/zeroclaw-config/src/schema.rs:16624
if !is_tls && !is_plain {
anyhow::bail!(
"amqp_url must start with 'amqp://' or 'amqps://', got: {}",
self.amqp_url
);
}
if is_tls && self.ca_cert.is_none() {
anyhow::bail!("amqps:// requires ca_cert to verify the broker");
}
match (self.client_cert.is_some(), self.client_key.is_some()) {
(true, false) => {
anyhow::bail!(
"client_cert is set but client_key is missing (both are required for mutual TLS)"
)
}
(false, true) => {
anyhow::bail!(
"client_key is set but client_cert is missing (both are required for mutual TLS)"
)
}
_ => {}
}
if self.exchange.is_empty() {
validation_bail!(RequiredFieldEmpty, "exchange", "exchange must not be empty");
}
if self.routing_keys.is_empty() {
anyhow::bail!("at least one routing key must be configured");
}
Ok(())
}
}
View on GitHub (pinned to 88bb9c8533)
Solutions
- Add the matching certificate: `client_cert = "/etc/zeroclaw/client.pem"`.
- Check the exact field names `client_cert` / `client_key` — unknown keys are silently ignored, which produces exactly this error.
- Verify the pair matches before reloading.
Example fix
# before client_key = "/etc/zeroclaw/client.key" # client_cert missing # after client_key = "/etc/zeroclaw/client.key" client_cert = "/etc/zeroclaw/client.pem"
Defensive patterns
Strategy: validation
Validate before calling
anyhow::ensure!(
cfg.client_cert.is_some() == cfg.client_key.is_some(),
"client_cert and client_key must be set together"
); Type guard
fn mtls_pair_consistent(cert: &Option<PathBuf>, key: &Option<PathBuf>) -> bool {
cert.is_some() == key.is_some()
} Prevention
- Check for mistyped key names — unknown TOML keys are ignored, which looks like a missing field.
- Secrets-injection tooling should inject both paths or neither.
- Keep the two paths adjacent in the config file so half-edits are obvious.
When it happens
Trigger: `client_key = "/etc/zeroclaw/client.key"` with no `client_cert`; deleting or commenting the cert line while testing; reordered config where the cert key name was mistyped (e.g. `cert`) and thus ignored.
Common situations: Hand-editing mTLS blocks and dropping one line; secrets tooling that injects the key but fails to inject the cert path; key-past-first muscle memory when filling in PEM paths.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- client_cert is set but client_key is missing (both are requi
- amqp_url must start with 'amqp://' or 'amqps://', got: {}
- amqps:// requires ca_cert to verify the broker
- at least one routing key must be configured
- amqp channel '{}': client_cert is set but client_key is miss
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/f7b7202de3777ccd.
Report an issue: GitHub.