{"record":{"id":"4a850381afa108c6","repo":"caddyserver/caddy","slug":"loading-intermediate-key-v","errorCode":null,"errorMessage":"loading intermediate key: %v","messagePattern":"loading intermediate key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"modules/caddypki/ca.go","lineNumber":372,"sourceCode":"\t\tinterCert, interKey, err = ca.genIntermediate(rootCert, rootKey)\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"generating new intermediate cert: %v\", err)\n\t\t}\n\n\t\tinterCertChain = append(interCertChain, interCert)\n\t}\n\n\tif len(interCertChain) == 0 {\n\t\tinterCertChain, err = pemDecodeCertificateChain(interCertPEM)\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"decoding intermediate certificate PEM: %v\", err)\n\t\t}\n\t}\n\n\tif interKey == nil {\n\t\tinterKeyPEM, err := ca.storage.Load(ca.ctx, ca.storageKeyIntermediateKey())\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"loading intermediate key: %v\", err)\n\t\t}\n\t\tinterKey, err = certmagic.PEMDecodePrivateKey(interKeyPEM)\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"decoding intermediate key: %v\", err)\n\t\t}\n\t}\n\n\treturn interCertChain, interKey, nil\n}\n\nfunc (ca CA) genIntermediate(rootCert *x509.Certificate, rootKey crypto.Signer) (interCert *x509.Certificate, interKey crypto.Signer, err error) {\n\trepl := ca.newReplacer()\n\n\tinterCert, interKey, err = generateIntermediate(repl.ReplaceAll(ca.IntermediateCommonName, \"\"), rootCert, rootKey, time.Duration(ca.IntermediateLifetime))\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"generating CA intermediate: %v\", err)\n\t}\n\tinterCertPEM, err := pemEncodeCert(interCert.Raw)","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddypki/ca.go#L354-L390","documentation":"After loading an intermediate cert chain from storage, Caddy loads the intermediate private key (storageKeyIntermediateKey). Any storage error is wrapped as 'loading intermediate key'. Without the intermediate key the CA cannot sign leaf certificates, so setup fails even though the chain parsed fine.","triggerScenarios":"storage.Load for the intermediate key errors: object deleted while intermediate.crt remains (partial state), permission/ownership problem on key.pem, custom storage backend failure. Runs on the load-existing path (interKey == nil after no generation happened).","commonSituations":"Key file removed separately from the cert (security cleanup gone wrong); backups that skipped key files; inconsistent replicated storage across nodes; storage prefix moved without copying all objects.","solutions":["Restore intermediate key.pem to the expected storage key so it pairs with intermediate.crt.","If lost, delete both intermediate cert and key objects (keep root) and restart to regenerate the intermediate; leafs signed by the old intermediate stay valid until expiry, new leafs come from the new one.","Repair permissions on the CA storage directory.","Ensure backups and multi-node storage copies always include every CA asset."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-start: cert without key = partial state\n_, c := os.Stat(caDir + \"/intermediate.crt\")\n_, k := os.Stat(caDir + \"/intermediate.key.pem\")\nif c == nil && k != nil { fail(\"intermediate key missing\") }","typeGuard":"func intermediateAssetsComplete(dir string) bool {\n    _, c := os.Stat(filepath.Join(dir, \"intermediate.crt\"))\n    _, k := os.Stat(filepath.Join(dir, \"intermediate.key.pem\"))\n    return (c == nil) == (k == nil)\n}","tryCatchPattern":"if strings.Contains(err.Error(), \"loading intermediate key\") {\n    // restore key, or drop intermediate cert+key objects to force regeneration under root\n}","preventionTips":["Back up intermediate cert and key as a pair.","Never delete one half of a CA asset pair during cleanup.","Run asset-completeness checks after every restore or node sync."],"tags":["pki","intermediate-key","storage","partial-state"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}