{"record":{"id":"b3b6239e8e7c7b02","repo":"caddyserver/caddy","slug":"decoding-intermediate-certificate-pem-v","errorCode":null,"errorMessage":"decoding intermediate certificate PEM: %v","messagePattern":"decoding intermediate certificate PEM: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"modules/caddypki/ca.go","lineNumber":365,"sourceCode":"\tinterCertPEM, err := ca.storage.Load(ca.ctx, ca.storageKeyIntermediateCert())\n\tif err != nil {\n\t\tif !errors.Is(err, fs.ErrNotExist) {\n\t\t\treturn nil, nil, fmt.Errorf(\"loading intermediate cert: %v\", err)\n\t\t}\n\n\t\t// TODO: should we require that all or none of the assets are required before overwriting anything?\n\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) {","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddypki/ca.go#L347-L383","documentation":"An intermediate certificate PEM was loaded from storage, but pemDecodeCertificateChain could not parse it into a chain of x509 certificates. The stored intermediate.crt is corrupt, truncated, or contains a non-certificate PEM block. Because the intermediate is what signs leafs, this stops all issuance even though the root is fine.","triggerScenarios":"storage.Load succeeds but the bytes fail PEM/x509 chain parsing: file truncated by a crash mid-write, a key PEM stored in intermediate.crt, base64 corruption, CRLF/BOM injected by editors or replication. Any startup/load of an existing CA with a stored intermediate.","commonSituations":"Partial writes from disk-full events (see the file's all-or-none TODO); operators editing or moving storage files by hand; storage replication mangling objects; backups restored incompletely.","solutions":["Verify and, if corrupt, delete only the intermediate cert+key objects in storage (keep root) and restart — Caddy will regenerate a fresh intermediate signed by the existing root, and existing leafs remain valid until expiry.","Restore a known-good intermediate.crt/key.pem pair from backup instead, if you need continuity of the intermediate.","Fix disk space / storage atomicity so Store() cannot half-write again.","Stop hand-editing storage objects; use Caddy's API/CLI for exports."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-start: parse stored intermediate chain\nif b, err := os.ReadFile(caDir + \"/intermediate.crt\"); err == nil {\n    if _, err := parseCertChainPEM(b); err != nil { fail(\"intermediate cert corrupt\") }\n}","typeGuard":"func isParseableCertChainPEM(b []byte) bool {\n    rest := b\n    for {\n        var block *pem.Block\n        block, rest = pem.Decode(rest)\n        if block == nil { break }\n        if block.Type != \"CERTIFICATE\" { return false }\n        if _, err := x509.ParseCertificate(block.Bytes); err != nil { return false }\n    }\n    return len(rest) == 0\n}","tryCatchPattern":"if strings.Contains(err.Error(), \"decoding intermediate certificate PEM\") {\n    // delete intermediate cert+key only (keep root) -> Caddy regenerates under same root\n}","preventionTips":["Treat CA storage as opaque; never edit intermediate.crt by hand.","Verify storage integrity after restores/migrations.","Detect and clean partial writes (file size 0 or truncated PEM footer) in pre-start checks."],"tags":["pki","intermediate","pem","corruption"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}