{"record":{"id":"b95699d65ae21b0d","repo":"siyuan-note/siyuan","slug":"failed-to-write-ca-private-key-w","errorCode":null,"errorMessage":"failed to write CA private key: %w","messagePattern":"failed to write CA private key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/cert.go","lineNumber":348,"sourceCode":"\tkeyBlock, _ := pem.Decode([]byte(caKeyPEM))\n\tif keyBlock == nil {\n\t\treturn fmt.Errorf(\"failed to decode CA private key PEM\")\n\t}\n\n\t_, err = x509.ParseECPrivateKey(keyBlock.Bytes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse CA private key: %w\", err)\n\t}\n\n\tcaCertPath := filepath.Join(ConfDir, TLSCACertFilename)\n\tcaKeyPath := filepath.Join(ConfDir, TLSCAKeyFilename)\n\n\tif err := os.WriteFile(caCertPath, []byte(caCertPEM), 0644); err != nil {\n\t\treturn fmt.Errorf(\"failed to write CA certificate: %w\", err)\n\t}\n\n\tif err := os.WriteFile(caKeyPath, []byte(caKeyPEM), 0600); err != nil {\n\t\treturn fmt.Errorf(\"failed to write CA private key: %w\", err)\n\t}\n\n\tcertPath := filepath.Join(ConfDir, TLSCertFilename)\n\tkeyPath := filepath.Join(ConfDir, TLSKeyFilename)\n\n\tif gulu.File.IsExist(certPath) {\n\t\tos.Remove(certPath)\n\t}\n\tif gulu.File.IsExist(keyPath) {\n\t\tos.Remove(keyPath)\n\t}\n\n\tlogging.LogInfof(\"imported CA bundle, server certificate will be regenerated on next TLS initialization\")\n\treturn nil\n}\n\n// trimIPv6Brackets removes brackets from IPv6 address strings like \"[::1]\"\nfunc trimIPv6Brackets(ip string) string {","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/cert.go#L330-L366","documentation":"Error from ImportCABundle when os.WriteFile fails to persist the CA private key PEM to the TLS conf directory: disk error, missing directory, or insufficient permissions — the imported CA bundle cannot be fully installed.","triggerScenarios":"os.WriteFile(caKeyPath, ..., 0600) fails — ConfDir missing/unwritable, read-only filesystem, disk full, or permission denied for the key path (which may have stricter ACLs than the cert).","commonSituations":"The kernel runs under a service account lacking write permission to the workspace conf dir; the key file exists with root-only ownership from a previous run; read-only container filesystem.","solutions":["Make the conf directory writable by the kernel process user (chown/chmod)","If an old ca key file exists with wrong ownership, remove or chown it first","Verify the filesystem is writable and has free space, then retry"],"exampleFix":"// before\n// ca.key owned by root in workspace conf dir -> 0600 write denied\n// after\n// sudo chown <kernel-user> <workspace>/conf/tls-ca-key.pem\nImportCABundle(caCertPEM, caKeyPEM)","handlingStrategy":"try-catch","validationCode":"info, err := os.Stat(caKeyPath); canWrite := err != nil || info.Mode().Perm()&0200 != 0","typeGuard":null,"tryCatchPattern":"if err := util.ImportCABundle(caCertPEM, caKeyPEM); err != nil {\n    if strings.Contains(err.Error(), \"failed to write CA private key\") {\n        // check ownership/ACL of the existing key file in conf dir\n    }\n}","preventionTips":["Pre-create the key path with ownership by the kernel service user","Remove stale root-owned key files after changing run users","Prefer running the kernel in a writable data directory, not a read-only container layer"],"tags":["tls","filesystem","private-key","permissions"],"backgroundTag":"file-write-permission-denied","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}