{"record":{"id":"a80762b67878dbc2","repo":"caddyserver/caddy","slug":"loading-signing-key-v","errorCode":null,"errorMessage":"loading signing key: %v","messagePattern":"loading signing key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"modules/caddypki/ca.go","lineNumber":238,"sourceCode":"// executes at a later time, always has the only copy of the CA so it can access the latest,\n// renewed certificates since NewAuthority was called. See #4517 and #4669.\nfunc (ca *CA) NewAuthority(authorityConfig AuthorityConfig) (*authority.Authority, error) {\n\t// get the root certificate and the issuer cert+key\n\trootCert := ca.RootCertificate()\n\n\t// set up the signer; cert/key which signs the leaf certs\n\tvar signerOption authority.Option\n\tif authorityConfig.SignWithRoot {\n\t\t// if we're signing with root, we can just pass the\n\t\t// cert/key directly, since it's unlikely to expire\n\t\t// while Caddy is running (long lifetime)\n\t\tvar issuerCert *x509.Certificate\n\t\tvar issuerKey crypto.Signer\n\t\tissuerCert = rootCert\n\t\tvar err error\n\t\tissuerKey, err = ca.RootKey()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"loading signing key: %v\", err)\n\t\t}\n\t\tsignerOption = authority.WithX509Signer(issuerCert, issuerKey)\n\t} else {\n\t\t// if we're signing with intermediate, we need to make\n\t\t// sure it's always fresh, because the intermediate may\n\t\t// renew while Caddy is running (medium lifetime)\n\t\tsignerOption = authority.WithX509SignerFunc(func() ([]*x509.Certificate, crypto.Signer, error) {\n\t\t\tissuerChain := ca.IntermediateCertificateChain()\n\t\t\tissuerCert := issuerChain[0]\n\t\t\tissuerKey := ca.IntermediateKey()\n\t\t\tca.log.Debug(\"using intermediate signer\",\n\t\t\t\tzap.String(\"serial\", issuerCert.SerialNumber.String()),\n\t\t\t\tzap.String(\"not_before\", issuerCert.NotBefore.String()),\n\t\t\t\tzap.String(\"not_after\", issuerCert.NotAfter.String()))\n\t\t\treturn issuerChain, issuerKey, nil\n\t\t})\n\t}\n","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddypki/ca.go#L220-L256","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\n{\"root\":{\"cert\":\"file:///etc/caddy/root.crt\"},\"sign_with_root\":true}\n// after\n{\"root\":{\"cert\":\"file:///etc/caddy/root.crt\",\"key\":\"file:///etc/caddy/root.key\"},\"sign_with_root\":true}","handlingStrategy":"try-catch","validationCode":"// Before starting Caddy with sign_with_root, confirm both assets exist\n// (example for file storage): check <storage>/caddy/pki/<id>/ca/root.crt AND key.pem\nif _, err := os.Stat(rootKeyPath); err != nil { log.Fatal(\"root key missing for sign_with_root\") }","typeGuard":null,"tryCatchPattern":"// err is returned from CA provisioning; check prefix and surface actionable text\nif err != nil {\n    if strings.Contains(err.Error(), \"loading signing key\") {\n        // inspect storage for the root key object; re-import root{cert,key} pair\n    }\n    return fmt.Errorf(\"pki CA setup failed: %v\", err)\n}","preventionTips":["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)."],"tags":["pki","signing","root-key","storage"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}