caddyserver/caddy · error

unrecognized public key algorithm: %s (expected one of %v)

Error message

unrecognized public key algorithm: %s (expected one of %v)

What it means

PublicKeyAlgorithm.UnmarshalJSON maps a string to an x509.PublicKeyAlgorithm for TLS verification settings (e.g. verifiers' public_key_algorithms lists). The string (lowercased, quotes trimmed) must be a key of the internal map — the standard algorithm names such as 'rsa', 'ed25519', 'ecdsa', 'dsa' variants; anything else errors with the accepted list included in the message.

Source

Thrown at modules/caddytls/connpolicy.go:1056

		return fmt.Errorf("can't parse the given certificate: %s", err.Error())
	}

	if slices.ContainsFunc(l.trustedLeafCerts, remoteLeafCert.Equal) {
		return nil
	}

	return fmt.Errorf("client leaf certificate failed validation")
}

// PublicKeyAlgorithm is a JSON-unmarshalable wrapper type.
type PublicKeyAlgorithm x509.PublicKeyAlgorithm

// UnmarshalJSON satisfies json.Unmarshaler.
func (a *PublicKeyAlgorithm) UnmarshalJSON(b []byte) error {
	algoStr := strings.ToLower(strings.Trim(string(b), `"`))
	algo, ok := publicKeyAlgorithms[algoStr]
	if !ok {
		return fmt.Errorf("unrecognized public key algorithm: %s (expected one of %v)",
			algoStr, publicKeyAlgorithms)
	}
	*a = PublicKeyAlgorithm(algo)
	return nil
}

// ConnectionMatcher is a type which matches TLS handshakes.
type ConnectionMatcher interface {
	Match(*tls.ClientHelloInfo) bool
}

// LeafCertificateLoader is a type that loads the trusted leaf certificates
// for the tls.leaf_cert_loader modules
type LeafCertificateLoader interface {
	LoadLeafCertificates() ([]*x509.Certificate, error)
}

// ClientCertificateVerifier is a type which verifies client certificates.

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Use the algorithm names from the error message's expected list (it prints the valid map) — typically: rsa, dsa, ecdsa, ed25519
  2. Drop JOSE-style names: RS256->rsa, ES256/ECDSA->ecdsa, Ed25519->ed25519
  3. Run caddy validate on the JSON to fail fast before reload

Example fix

// before
"verifier": {"module": "leaf", "public_key_algorithms": ["RS256"]}

// after
"verifier": {"module": "leaf", "public_key_algorithms": ["rsa"]}
Defensive patterns

Strategy: validation

Validate before calling

var validPKAlgorithms = map[string]bool{
	"rsa": true, "dsa": true, "ecdsa": true, "ed25519": true,
}
func validateAlgoList(algos []string) error {
	for _, a := range algos {
		if !validPKAlgorithms[strings.ToLower(a)] {
			return fmt.Errorf("public key algorithm %q not recognized; use x509 algorithm names (rsa, ecdsa, ed25519...)", a)
		}
	}
	return nil
}

Type guard

func isX509AlgorithmName(s string) bool {
	_, ok := map[string]struct{}{"rsa": {}, "dsa": {}, "ecdsa": {}, "ed25519": {}}[strings.ToLower(s)]
	return ok
}

Prevention

When it happens

Trigger: Writing "public_key_algorithms": ["RS256"] or ["RSA-2048"] or ["P256"] in JSON verification config instead of the Go algorithm names like "rsa" or "ecdsa".

Common situations: Confusing JWS/JOSE algorithm identifiers (RS256, ES256) or curve names (P-256) with x509 public key algorithm names; uppercase spellings are tolerated via ToLower but hyphenated or prefixed names are not.

Related errors


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