caddyserver/caddy · error

encoding intermediate certificate: %v

Error message

encoding intermediate certificate: %v

What it means

After generating a new intermediate certificate, Caddy PEM-encodes it (pemEncodeCert on interCert.Raw) before storing; failure is wrapped as 'encoding intermediate certificate'. Like the root-side encoding errors, this indicates the produced certificate failed PEM serialization — an internal invariant break or abnormal certificate content, not an environment problem.

Source

Thrown at modules/caddypki/ca.go:392

		interKey, err = certmagic.PEMDecodePrivateKey(interKeyPEM)
		if err != nil {
			return nil, nil, fmt.Errorf("decoding intermediate key: %v", err)
		}
	}

	return interCertChain, interKey, nil
}

func (ca CA) genIntermediate(rootCert *x509.Certificate, rootKey crypto.Signer) (interCert *x509.Certificate, interKey crypto.Signer, err error) {
	repl := ca.newReplacer()

	interCert, interKey, err = generateIntermediate(repl.ReplaceAll(ca.IntermediateCommonName, ""), rootCert, rootKey, time.Duration(ca.IntermediateLifetime))
	if err != nil {
		return nil, nil, fmt.Errorf("generating CA intermediate: %v", err)
	}
	interCertPEM, err := pemEncodeCert(interCert.Raw)
	if err != nil {
		return nil, nil, fmt.Errorf("encoding intermediate certificate: %v", err)
	}
	err = ca.storage.Store(ca.ctx, ca.storageKeyIntermediateCert(), interCertPEM)
	if err != nil {
		return nil, nil, fmt.Errorf("saving intermediate certificate: %v", err)
	}
	interKeyPEM, err := certmagic.PEMEncodePrivateKey(interKey)
	if err != nil {
		return nil, nil, fmt.Errorf("encoding intermediate key: %v", err)
	}
	err = ca.storage.Store(ca.ctx, ca.storageKeyIntermediateKey(), interKeyPEM)
	if err != nil {
		return nil, nil, fmt.Errorf("saving intermediate key: %v", err)
	}

	return interCert, interKey, nil
}

func (ca CA) storageKeyCAPrefix() string {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Run a current, unmodified Caddy build.
  2. Retry provisioning once to exclude transient faults.
  3. If reproducible, capture the wrapped error and CA config and report upstream; as a workaround, supply a pre-made intermediate via the intermediate{ cert/key } block.
Defensive patterns

Strategy: try-catch

Try / catch

// internal invariant: capture wrapped error, retry once, report upstream if repeated
if strings.Contains(err.Error(), "encoding intermediate certificate") {
    logErrorWithConfig(err, caConfig) // workaround: supply external intermediate{cert,key}
}

Prevention

When it happens

Trigger: genIntermediate's freshly signed intermediate has Raw bytes that pemEncodeCert rejects (empty/malformed DER from an upstream signing fault). Only reachable when an intermediate was just generated because none existed in storage.

Common situations: Very rare on stock builds; associated with forks injecting custom signers, corrupted library builds, or upstream smallstep/Go x509 regressions.

Understand the failure class

Related errors


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