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

  1. Set both `client-cert` and `client-key` to their PEM file paths.
  2. If mutual TLS is not required, remove the single orphan field entirely.
  3. 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

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

Related errors


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/4014db7f7688a23c. Report an issue: GitHub.