siyuan-note/siyuan · error
failed to write CA private key
Error message
failed to write CA private key: %w
What it means
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.
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
Example fix
// before // ca.key owned by root in workspace conf dir -> 0600 write denied // after // sudo chown <kernel-user> <workspace>/conf/tls-ca-key.pem ImportCABundle(caCertPEM, caKeyPEM)
Defensive patterns
Strategy: try-catch
Validate before calling
info, err := os.Stat(caKeyPath); canWrite := err != nil || info.Mode().Perm()&0200 != 0
Try / catch
if err := util.ImportCABundle(caCertPEM, caKeyPEM); err != nil {
if strings.Contains(err.Error(), "failed to write CA private key") {
// check ownership/ACL of the existing key file in conf dir
}
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- Conf.Language(14) (copy resource failed: )
- create AI editor actions directory failed
- create conf dir failed
- create import dir failed:
- create import dir failed
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/b95699d65ae21b0d.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/util/cert.go:348
keyBlock, _ := pem.Decode([]byte(caKeyPEM))
if keyBlock == nil {
return fmt.Errorf("failed to decode CA private key PEM")
}
_, err = x509.ParseECPrivateKey(keyBlock.Bytes)
if err != nil {
return fmt.Errorf("failed to parse CA private key: %w", err)
}
caCertPath := filepath.Join(ConfDir, TLSCACertFilename)
caKeyPath := filepath.Join(ConfDir, TLSCAKeyFilename)
if err := os.WriteFile(caCertPath, []byte(caCertPEM), 0644); err != nil {
return fmt.Errorf("failed to write CA certificate: %w", err)
}
if err := os.WriteFile(caKeyPath, []byte(caKeyPEM), 0600); err != nil {
return fmt.Errorf("failed to write CA private key: %w", err)
}
certPath := filepath.Join(ConfDir, TLSCertFilename)
keyPath := filepath.Join(ConfDir, TLSKeyFilename)
if gulu.File.IsExist(certPath) {
os.Remove(certPath)
}
if gulu.File.IsExist(keyPath) {
os.Remove(keyPath)
}
logging.LogInfof("imported CA bundle, server certificate will be regenerated on next TLS initialization")
return nil
}
// trimIPv6Brackets removes brackets from IPv6 address strings like "[::1]"
func trimIPv6Brackets(ip string) string {View on GitHub (pinned to 9f775e8a12)