caddyserver/caddy · error

private key does not match issuer public key

Error message

private key does not match issuer public key

What it means

meta.json loaded but json.Unmarshal into echConfigMeta failed — the metadata is present but not valid JSON of the expected shape. Caddy's policy is to reset the whole config folder (it cannot reliably maintain a config without metadata), and that cleanup delete failed as well.

Source

Thrown at modules/caddypki/crypto.go:135

		return chain, key, nil

	default:
		return nil, nil, fmt.Errorf("unsupported format: %s", kp.Format)
	}
}

// verifyKeysMatch verifies that the public key in the [x509.Certificate] matches
// the public key of the [crypto.Signer].
func verifyKeysMatch(crt *x509.Certificate, signer crypto.Signer) error {
	switch pub := crt.PublicKey.(type) {
	case *rsa.PublicKey:
		pk, ok := signer.Public().(*rsa.PublicKey)
		if !ok {
			return fmt.Errorf("private key type %T does not match issuer public key type %T", signer.Public(), pub)
		}
		if !pub.Equal(pk) {
			return errors.New("private key does not match issuer public key")
		}
	case *ecdsa.PublicKey:
		pk, ok := signer.Public().(*ecdsa.PublicKey)
		if !ok {
			return fmt.Errorf("private key type %T does not match issuer public key type %T", signer.Public(), pub)
		}
		if !pub.Equal(pk) {
			return errors.New("private key does not match issuer public key")
		}
	case ed25519.PublicKey:
		pk, ok := signer.Public().(ed25519.PublicKey)
		if !ok {
			return fmt.Errorf("private key type %T does not match issuer public key type %T", signer.Public(), pub)
		}
		if !pub.Equal(pk) {
			return errors.New("private key does not match issuer public key")
		}
	default:

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Restore writable storage so the cleanup can proceed.
  2. Manually delete the affected ech/configs/<id> folder (or the whole ech/configs tree if several configs are affected) and restart Caddy to regenerate.
  3. Verify storage health (fsync/atomicity) if truncation recurs; prefer the default file storage or a backend with atomic puts.
  4. Avoid hand-editing files under Caddy's storage.

Example fix

# before: truncated metadata blocks cleanup on read-only storage
# after: remount writable, then reset the folder
mount -o remount,rw /var/lib/caddy
rm -rf /var/lib/caddy/ech/configs/42
systemctl restart caddy
Defensive patterns

Strategy: fallback

Try / catch

On JSON-decode failure, Caddy's fallback is folder reset; it only errors when that reset fails — restore storage writability, remove the named ech/configs/<id> folder (or the whole tree), restart.

Prevention

When it happens

Trigger: json.Unmarshal of non-empty metaBytes errors (truncated JSON from an interrupted write, manual edits, schema change across versions) AND storage.Delete of the config folder errors (read-only/outage).

Common situations: Crash during a metadata Store leaving a truncated meta.json; storage backends without atomic writes; mixed-version clusters where the metadata schema evolved; combined with a storage backend that cannot delete.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/b0fb178eae5a5fab. Report an issue: GitHub.