gravitational/teleport · error
invalid public key
Error message
invalid public key
What it means
validateCertificateOverride rejects the override's public_key when it does not match the expected PEM public key format (certificateOverridePublicKeyRE) or when an accompanying certificate is present whose public key hash differs from the supplied public_key. This guards subCA overrides against malformed or mismatched key material.
Source
Thrown at lib/subca/parsed.go:246
// Certificate.
var cert *x509.Certificate
var wantPublicKey string
if co.GetCertificate() != "" {
var err error
cert, err = ParseCertificateOverrideCertificate(co.GetCertificate())
if err != nil {
return nil, "certificate", err
}
if err := validateOverrideCertificate(clusterName, cert); err != nil {
return nil, "certificate", err
}
wantPublicKey = HashCertificatePublicKey(cert)
}
// PublicKey.
if co.GetPublicKey() != "" {
if !certificateOverridePublicKeyRE.MatchString(co.GetPublicKey()) {
return nil, "", errors.New("invalid public key")
}
if wantPublicKey != "" && NormalizePublicKey(co.GetPublicKey()) != wantPublicKey {
return nil, "public_key", fmt.Errorf("certificate public key mismatch (want %q)", wantPublicKey)
}
}
// Validate "required" fields now that we know both Certificate and PublicKey
// are valid.
switch {
case co.GetDisabled() && co.GetPublicKey() == "" && co.GetCertificate() == "":
return nil, "", errors.New("certificate or public key required")
case co.GetDisabled():
// OK, determined above to have either PublicKey or Certificate.
case co.GetCertificate() == "":
return nil, "", errors.New("certificate required")
}
// Chain.View on GitHub (pinned to 1283425b60)
Solutions
- Provide the public key as a valid PEM-encoded PUBLIC KEY block
- If both certificate and public_key are set, ensure the public key matches the certificate's key (or omit public_key and let it be derived from the certificate)
- Regenerate/extract the key with openssl: openssl x509 -in cert.pem -pubkey -noout
Example fix
// before: mismatched public_key + certificate override: certificate: <cert A> public_key: <key from cert B> // after: derive from certificate override: certificate: <cert A>
Defensive patterns
Strategy: validation
Validate before calling
pub, ok := normalizePublicKeyPEM(override.GetPublicKey())
if !ok { return trace.BadParameter("public_key must be PEM-encoded PUBLIC KEY") }
if override.GetCertificate() != "" {
cert := parseCert(t, override.GetCertificate())
if normalize(pub) != hashCertPub(cert) {
return trace.BadParameter("public_key does not match certificate")
}
} Type guard
func publicKeyMatchesCert(certPEM, pubPEM string) bool {
cert, err := subca.ParseCertificatePEM(certPEM); if err != nil { return false }
return subca.NormalizePublicKey(pubPEM) == subca.HashCertificatePublicKey(cert)
} Try / catch
_, field, err := ValidateAndParseCAOverride(clusterName, co)
if field == "public_key" {
return trace.BadParameter("override public_key invalid or does not match certificate")
} Prevention
- Derive public_key from the same certificate instead of pasting separately
- Use openssl x509 -pubkey -noout to extract the exact PEM public key
- Never paste private keys or full certs into the public_key field
When it happens
Trigger: Providing co.PublicKey that is not a valid PEM public key string, or providing both certificate and public_key where NormalizePublicKey(public_key) != HashCertificatePublicKey(cert).
Common situations: Copy-pasting a public key with wrong PEM headers/extra whitespace; supplying a public_key from a different certificate than the override's certificate; pasting a private key or certificate where a public key is expected.
Related errors
- nil certificate override
- certificate required
- certificate or public key required
- chain not allowed with an empty certificate
- not a CA certificate (IsCA=false)
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/cc32d0671147ef92.
Report an issue: GitHub.