hatoo/oha · error · anyhow::Error
Both --cert and --key must be specified
Error message
Both --cert and --key must be specified
What it means
Mutual TLS client authentication requires both a client certificate (--cert) and its private key (--key). The match on (cert, key) handles Some/Some and None/None; any mixed combination bails. The comment notes clap's requires rules normally make this unreachable, but the code defends defensively.
Solutions
- Always pass --cert and --key together when using mTLS.
- Pass neither if client authentication is not needed.
- Verify the option-construction path isn't setting only one field.
Example fix
// before oha --cert client.pem https://example.com // after oha --cert client.pem --key client-key.pem https://example.com
Defensive patterns
Strategy: validation
Validate before calling
if opt_cert.is_some() != opt_key.is_some() {
return Err("--cert and --key must be provided together".into());
} Try / catch
match run(opts).await {
Err(e) if e.to_string().contains("Both --cert and --key must be specified") => {
eprintln!("mTLS requires both --cert and --key");
}
Err(e) => return Err(e),
Ok(v) => v,
} Prevention
- Always set --cert and --key as a pair in mTLS configurations.
- Rely on clap requires rules rather than building opts programmatically.
- Validate option structs before handing them to run().
When it happens
Trigger: Programmatic construction of run options bypassing clap validation, providing exactly one of --cert or --key.
Common situations: Rarely hit via normal CLI use because clap enforces the pairing; can appear with generated configs or custom option builders that skip clap parsing.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Invalid AWS credentials format. Expected…
- AWS credentials (--auth) required when using --aws-sigv4
- --http2 and --http-version are exclusive
- Your Oha instance has not been built with HTTP/3 support…
- Unknown HTTP version. Valid versions are 0.9, 1.0, 1.1, 2, 3
AI-assisted analysis of hatoo/oha@4efba2d113 (2026-09-09).
Data as JSON: /api/errors/f715bc9cebd2b378.
Report an issue: GitHub.
Appendix: source
Thrown at src/main.rs:587
}
(true, false) => hickory_resolver::config::LookupIpStrategy::Ipv4Only,
(false, true) => hickory_resolver::config::LookupIpStrategy::Ipv6Only,
(true, true) => hickory_resolver::config::LookupIpStrategy::Ipv4AndIpv6,
};
let (config, mut resolver_opts) = system_resolv_conf()?;
resolver_opts.ip_strategy = ip_strategy;
let resolver = hickory_resolver::Resolver::builder_with_config(
config,
hickory_resolver::net::runtime::TokioRuntimeProvider::default(),
)
.with_options(resolver_opts)
.build()?;
let cacert = opts.cacert.as_deref().map(std::fs::read).transpose()?;
let client_auth = match (opts.cert, opts.key) {
(Some(cert), Some(key)) => Some((std::fs::read(cert)?, std::fs::read(key)?)),
(None, None) => None,
// Not possible because of clap requires
_ => anyhow::bail!("Both --cert and --key must be specified"),
};
let url = url.into_owned();
let client = Arc::new(client::Client {
request_generator: RequestGenerator {
url_generator,
https: url.scheme() == "https",
version: http_version,
aws_config,
method,
headers,
body_generator,
http_proxy: if opts.proxy.is_some() && url.scheme() == "http" {
Some(Proxy {
headers: proxy_headers.clone(),
version: proxy_http_version,
})
} else {View on GitHub (pinned to 4efba2d113)