gravitational/teleport · error
certificate required
Error message
certificate required
What it means
An enabled (not disabled) certificate override must supply a certificate — a public key alone is insufficient for an active override because the CA needs the actual certificate to issue from. validateCertificateOverride returns this error when co.Disabled is false and co.Certificate is empty.
Source
Thrown at lib/subca/parsed.go:261
// 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.
var chain []*x509.Certificate
if len(co.GetChain()) > 0 {
if cert == nil {
return nil, "", errors.New("chain not allowed with an empty certificate")
}
// The exact number is arbitrary, the fact that a cap exists isn't.
const maxChainLength = 10
if len(co.GetChain()) > maxChainLength {
return nil, "chain", fmt.Errorf(
"certificate chain has too many entries (%d > %d)", len(co.GetChain()), maxChainLength)
}
chain = make([]*x509.Certificate, len(co.GetChain()))
prev := certView on GitHub (pinned to 1283425b60)
Solutions
- Provide the PEM certificate in the override's certificate field
- Set disabled: true if the override is only meant to pin/deny a key without active issuance
Example fix
// before (enabled override, no cert)
override:
public_key: <pem>
// after
override:
certificate: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE----- Defensive patterns
Strategy: validation
Validate before calling
if !override.GetDisabled() && override.GetCertificate() == "" {
return trace.BadParameter("enabled certificate override requires a certificate")
} Type guard
func isEnabledOverrideComplete(o *subcav1.CertificateOverride) bool {
return o != nil && (o.GetDisabled() || o.GetCertificate() != "")
} Try / catch
if _, _, err := ValidateAndParseCAOverride(clusterName, co); err != nil {
if strings.Contains(err.Error(), "certificate required") {
return trace.BadParameter("provide a PEM certificate or set disabled: true")
}
return trace.Wrap(err)
} Prevention
- Set disabled:true for key-only overrides
- Always include the PEM certificate for active overrides
- Validate specs in CI before applying SubCA resources
When it happens
Trigger: Creating a SubCA certificate override with only public_key set and disabled false (or unset), reaching the final case of the required-fields switch.
Common situations: Intending to disable an override but forgetting disabled:true while omitting the certificate; using a public-key-only spec copied from a disabled override.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- nil certificate override
- invalid public key
- 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/bb698885badd9b6d.
Report an issue: GitHub.