hashicorp/nomad · error
error generating CA certificate: %s
Error message
error generating CA certificate: %s
What it means
GenerateCA failed at the x509.CreateCertificate step when building the self-signed CA certificate. The crypto/x509 layer rejected the template/signer combination, and the underlying Go error is wrapped into this message. It means the CA could not be minted at all, so no cert or key material is returned.
Source
Thrown at helper/tlsutil/generate.go:195
CommonName: opts.Name,
},
BasicConstraintsValid: true,
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign | x509.KeyUsageDigitalSignature,
IsCA: true,
NotAfter: time.Now().AddDate(0, 0, opts.Days),
NotBefore: time.Now(),
AuthorityKeyId: id,
SubjectKeyId: id,
}
if len(opts.PermittedDNSDomains) > 0 {
template.PermittedDNSDomainsCritical = true
template.PermittedDNSDomains = opts.PermittedDNSDomains
}
bs, err := x509.CreateCertificate(
rand.Reader, &template, &template, signer.Public(), signer)
if err != nil {
return "", "", fmt.Errorf("error generating CA certificate: %s", err)
}
var buf bytes.Buffer
err = pem.Encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: bs})
if err != nil {
return "", "", fmt.Errorf("error encoding private key: %s", err)
}
return buf.String(), pk, nil
}
// GenerateCert generates a new certificate for agent TLS (not to be confused with Connect TLS)
func GenerateCert(opts CertOpts) (string, string, error) {
parent, err := parseCert(opts.CA)
if err != nil {
return "", "", err
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Read the wrapped %s detail from x509.CreateCertificate and fix the offending template field (most often the validity window or PermittedDNSDomains).
- Ensure opts.Duration is positive so template.NotAfter is after NotBefore.
- Verify PermittedDNSDomains entries are valid DNS names (no schemes, wildcards only as leading *.).
- Check the signer passed to GenerateCA is a valid ecdsa or rsa key generated with the matching GeneratePrivateKey.
- Confirm the host entropy/PRNG is functional (rand.Reader errors are rare but possible).
Example fix
// before
caCert, _, err := tlsutil.GenerateCA(tlsutil.CAOpts{Duration: 0})
// after
caCert, _, err := tlsutil.GenerateCA(tlsutil.CAOpts{Duration: 6 * 30 * 24 * time.Hour}) Defensive patterns
Strategy: validation
Validate before calling
func validCAOpts(o tlsutil.CAOpts) error {
if o.Duration <= 0 { return fmt.Errorf("CA duration must be positive") }
for _, d := range o.PermittedDNSDomains {
if d == "" { return fmt.Errorf("empty permitted DNS domain") }
}
switch o.Name {
case "": return fmt.Errorf("CA name required")
}
return nil
} Try / catch
caCert, pk, err := tlsutil.GenerateCA(opts)
if err != nil {
if strings.Contains(err.Error(), "error generating CA certificate") {
return fmt.Errorf("CA template rejected by x509: %w", err)
}
return err
} Prevention
- Always pass a positive Duration to GenerateCA.
- Use the library's GeneratePrivateKey for the signer so the key type is supported.
- Validate PermittedDNSDomains entries are plain DNS names.
- Log the wrapped x509 error detail when diagnosing template problems.
When it happens
Trigger: Calling helper/tlsutil.GenerateCA with a template the x509 package rejects: invalid validity window (NotAfter before NotBefore), malformed PermittedDNSDomains with PermittedDNSDomainsCritical=true, unsupported key type for the signer, or rand.Reader failure.
Common situations: Passing zero/negative Duration so NotAfter precedes NotBefore; misconfigured name-constraint domains; generating CAs on systems with a broken entropy source; custom callers building templates with unsupported extensions.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- common name value not provided
- country value not provided
- organization value not provided
- organizational unit value not provided
- certificate has expired or is not yet valid
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/c8436110f6896ed9.
Report an issue: GitHub.