caddyserver/caddy · critical
loading signing key: %v
Error message
loading signing key: %v
What it means
While building the embedded step-ca authority in sign_with_root mode, Caddy loads the root's private key via ca.RootKey(). If storage cannot return the key (missing, unreadable, or the root was imported cert-only without a key), newAuthority fails with this wrapped error. The CA then cannot sign anything until the key is available.
Source
Thrown at modules/caddypki/ca.go:238
// executes at a later time, always has the only copy of the CA so it can access the latest,
// renewed certificates since NewAuthority was called. See #4517 and #4669.
func (ca *CA) NewAuthority(authorityConfig AuthorityConfig) (*authority.Authority, error) {
// get the root certificate and the issuer cert+key
rootCert := ca.RootCertificate()
// set up the signer; cert/key which signs the leaf certs
var signerOption authority.Option
if authorityConfig.SignWithRoot {
// if we're signing with root, we can just pass the
// cert/key directly, since it's unlikely to expire
// while Caddy is running (long lifetime)
var issuerCert *x509.Certificate
var issuerKey crypto.Signer
issuerCert = rootCert
var err error
issuerKey, err = ca.RootKey()
if err != nil {
return nil, fmt.Errorf("loading signing key: %v", err)
}
signerOption = authority.WithX509Signer(issuerCert, issuerKey)
} else {
// if we're signing with intermediate, we need to make
// sure it's always fresh, because the intermediate may
// renew while Caddy is running (medium lifetime)
signerOption = authority.WithX509SignerFunc(func() ([]*x509.Certificate, crypto.Signer, error) {
issuerChain := ca.IntermediateCertificateChain()
issuerCert := issuerChain[0]
issuerKey := ca.IntermediateKey()
ca.log.Debug("using intermediate signer",
zap.String("serial", issuerCert.SerialNumber.String()),
zap.String("not_before", issuerCert.NotBefore.String()),
zap.String("not_after", issuerCert.NotAfter.String()))
return issuerChain, issuerKey, nil
})
}
View on GitHub (pinned to 50e54ee279)
Solutions
- Provide the root key alongside the root cert: add key_file to the root{} block (cert+key must both be present) or store the key at the expected storage path.
- Verify storage integrity: ensure the CA's root key object exists (e.g. ls storage/caddy/pki/<id>/ca/key.pem or your backend's equivalent) and that Caddy's storage user can read it.
- If you do not actually need root signing, remove sign_with_root so Caddy signs with a generated intermediate instead.
- If the key was lost, regenerate the CA (delete that CA's assets in storage) and re-distribute the new root to trust stores.
Example fix
// before
{"root":{"cert":"file:///etc/caddy/root.crt"},"sign_with_root":true}
// after
{"root":{"cert":"file:///etc/caddy/root.crt","key":"file:///etc/caddy/root.key"},"sign_with_root":true} Defensive patterns
Strategy: try-catch
Validate before calling
// Before starting Caddy with sign_with_root, confirm both assets exist
// (example for file storage): check <storage>/caddy/pki/<id>/ca/root.crt AND key.pem
if _, err := os.Stat(rootKeyPath); err != nil { log.Fatal("root key missing for sign_with_root") } Try / catch
// err is returned from CA provisioning; check prefix and surface actionable text
if err != nil {
if strings.Contains(err.Error(), "loading signing key") {
// inspect storage for the root key object; re-import root{cert,key} pair
}
return fmt.Errorf("pki CA setup failed: %v", err)
} Prevention
- Always import roots as a cert+key pair (root{ cert, key } blocks), never cert-only, when sign_with_root is enabled.
- Automate a pre-start check that every configured CA's key object is readable in storage.
- Keep storage backups as complete sets (cert, key, intermediate cert, intermediate key).
When it happens
Trigger: Enabling sign_with_root on a CA whose root key is absent from storage (root imported as cert only), a storage backend error while reading storageKeyRootKey, or a key PEM that fails to load. The call chain is CA.newAuthority -> ca.RootKey() -> storage.Load(root key).
Common situations: Users importing only root.cert_file without root.key_file; file/Redis/S3 storage permission problems or missing assets after partial provisioning; copied storage where the key file was excluded.
Related errors
- loading root key: %v
- saving root key: %v
- failed to get root and intermediate cert for CA %s: %v
- failed to provision CA %s, %w
- loading storage module: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/a80762b67878dbc2.
Report an issue: GitHub.