benbjohnson/litestream · error
client-cert and client-key must both be specified for mutual
Error message
client-cert and client-key must both be specified for mutual TLS authentication
What it means
NATS mutual TLS requires both a client certificate and its corresponding private key. newReplicaClientFromConfig rejects any configuration that specifies exactly one of `client-cert` / `client-key`, since a lone cert or key cannot form a valid TLS client identity.
Source
Thrown at cmd/litestream/main.go:1949
if bucketPath != "" {
bucket = strings.Trim(bucketPath, "/")
}
}
// Use bucket from config if not extracted from URL
if bucket == "" {
bucket = c.Bucket
}
// Ensure required settings are set
if bucket == "" {
return nil, fmt.Errorf("bucket required for NATS replica")
}
// Validate TLS configuration
// Both client cert and key must be specified together
if (c.ClientCert != "") != (c.ClientKey != "") {
return nil, fmt.Errorf("client-cert and client-key must both be specified for mutual TLS authentication")
}
// Build replica client
client := nats.NewReplicaClient()
client.URL = url
client.BucketName = bucket
// Set authentication options
client.JWT = c.JWT
client.Seed = c.Seed
client.Creds = c.Creds
client.NKey = c.NKey
client.Username = c.Username
client.Password = c.Password
client.Token = c.Token
// Set TLS options
if c.TLS != nil {View on GitHub (pinned to 4ed7a308f6)
Solutions
- Set both `client-cert` and `client-key` to their PEM file paths.
- If mutual TLS is not required, remove the single orphan field entirely.
- Check field spelling/casing so both values are actually parsed.
Example fix
# before
replicas:
- url: nats://nats.example.com
client-cert: /etc/litestream/client.pem
# after
replicas:
- url: nats://nats.example.com
client-cert: /etc/litestream/client.pem
client-key: /etc/litestream/client-key.pem Defensive patterns
Strategy: validation
Validate before calling
// Ensure mTLS fields come as a pair before building config
if (cfg.ClientCert != "") != (cfg.ClientKey != "") {
return fmt.Errorf("client-cert and client-key must be set together")
} Try / catch
if err := runReplicate(); err != nil {
if strings.Contains(err.Error(), "client-cert and client-key") {
// fix config to include both files
}
} Prevention
- Treat client-cert/client-key as one required pair in your config templates.
- Verify both PEM files exist and are readable before starting litestream.
When it happens
Trigger: Setting `client-cert: /path/cert.pem` without `client-key` (or vice versa) in a NATS replica config.
Common situations: Following mTLS docs that mention only the cert; key stored separately and forgotten; typo like `client_key` so one half silently parses as empty.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- invalid NATS URL: %w
- invalid scheme for NATS replica: %s
- bucket required for NATS replica
- bucket required for nats replica URL
- nats: failed to initialize object store: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/4014db7f7688a23c.
Report an issue: GitHub.