{"record":{"id":"3ecb539132109138","repo":"Billionmail/BillionMail","slug":"failed-to-save-private-key-v","errorCode":null,"errorMessage":"failed to save private key: %v","messagePattern":"failed to save private key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/acme/cli.go","lineNumber":210,"sourceCode":"\tfmt.Printf(\"  Valid from: %s\\n\", certInfo.NotBefore)\n\tfmt.Printf(\"  Valid to: %s\\n\", certInfo.NotAfter)\n\tfmt.Printf(\"  Domains: %s\\n\", strings.Join(certInfo.DNSNames, \", \"))\n\n\t// Certificate files\n\tcertificatePath := filepath.Join(cli.OutputPath, \"certificate.pem\")\n\tprivateKeyPath := filepath.Join(cli.OutputPath, \"private_key.pem\")\n\n\t// Save certificate and private key to files\n\t_, err = public.WriteFile(certificatePath, certificate)\n\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to save certificate: %v\", err)\n\t}\n\n\t_, err = public.WriteFile(privateKeyPath, privateKey)\n\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to save private key: %v\", err)\n\t}\n\n\tfmt.Printf(\"Certificate saved to: %s\\n\", certificatePath)\n\tfmt.Printf(\"Private key saved to: %s\\n\", privateKeyPath)\n\n\treturn certificatePath, privateKeyPath, nil\n}\n\n/**\n * @brief Save certificate to database\n * @return error\n */\nfunc (cli *AcmeCLI) SaveToDatabase(accountId int, certificate, privateKey string) (int, error) {\n\t// Get certificate info\n\tcertInfo := GetCertInfo(certificate)\n\tif certInfo.Subject == \"\" {\n\t\treturn 0, fmt.Errorf(\"invalid certificate\")\n\t}","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/acme/cli.go#L192-L228","documentation":"This error wraps the underlying filesystem failure that occurred while writing the ACME account private key to disk in AcmeCLI.Apply. After saving the certificate succeeds, the private key is written via public.WriteFile; any I/O error (permissions, missing directory, disk full) is wrapped with this message. It aborts the certificate issuance flow, returning empty paths.","triggerScenarios":"Calling Apply (directly or via applyCommand) when the target privateKeyPath directory does not exist, the process lacks write permission, the disk is full, or the path is invalid.","commonSituations":"Running the ACME CLI as a non-root user without write access to the config/cert directory; deploying in a container with a read-only filesystem; a typo in the configured key output path; parent directories never created before Apply runs.","solutions":["Check the wrapped %v detail to identify the actual filesystem error","Ensure the parent directory of privateKeyPath exists (os.MkdirAll) before calling Apply","Run the process with sufficient permissions or chown the output directory to the service user","Verify the disk is not full and the path is writable (touch a test file in that directory)","Use an absolute, valid path for the private key output"],"exampleFix":"// before\n_, err = public.WriteFile(privatePath, privateKey)\n// after\n_ = os.MkdirAll(filepath.Dir(privateKeyPath), 0700)\n_, err = public.WriteFile(privateKeyPath, privateKey)","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(filepath.Dir(privateKeyPath)); err != nil {\n    if err := os.MkdirAll(filepath.Dir(privateKeyPath), 0700); err != nil { return err }\n}\nif f, err := os.OpenFile(privateKeyPath, os.O_CREATE|os.O_WRONLY, 0600); err != nil { return err } else { f.Close() }","typeGuard":null,"tryCatchPattern":"certPath, keyPath, err := cli.Apply(...)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"failed to save private key\") {\n        log.Printf(\"key write failed: %v — check path permissions/disk\", err)\n    }\n    return err\n}","preventionTips":["Create the output directory with MkdirAll before Apply","Run the service with a user that owns the cert/key directory","Monitor disk space on the host storing certificates","Use absolute paths for key/cert outputs"],"tags":["filesystem","acme","file-write","permissions"],"backgroundTag":"file-write-permission-denied","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}