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
- Use the algorithm names from the error message's expected list (it prints the valid map) — typically: rsa, dsa, ecdsa, ed25519
- Drop JOSE-style names: RS256->rsa, ES256/ECDSA->ecdsa, Ed25519->ed25519
- 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
- Never use JOSE/JWT identifiers (RS256, ES256) in x509 algorithm lists
- The error message prints the valid map — read it and copy a key exactly
- Centralize verification config in a tested template
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
- not a valid big integer: %s
- recombining SNI matchers: %v
- module name not specified with key '%s' in %+v
- client_certificate_file specified without client_certificate
- client_certificate_key_file specified without client_certifi
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/fbcc4f9b662261a9.
Report an issue: GitHub.