siyuan-note/siyuan · error

failed to write CA certificate

Error message

failed to write CA certificate: %w

What it means

ImportCABundle writes the validated CA certificate PEM to <ConfDir>/TLSCACertFilename with mode 0644. This error wraps the os.WriteFile failure, so the cert was valid but could not be persisted to disk.

Solutions

  1. Ensure the workspace conf directory exists and is writable by the kernel process user
  2. Check disk space and that the volume is not mounted read-only
  3. Fix directory ownership/permissions (e.g. chown/chmod) and retry the import

Example fix

// before
// conf dir on read-only volume -> write fails
// after
os.MkdirAll(confDir, 0755) // ensure writable dir before ImportCABundle
ImportCABundle(caCertPEM, caKeyPEM)
Defensive patterns

Strategy: try-catch

Validate before calling

func canWrite(dir string) error {
    if err := os.MkdirAll(dir, 0755); err != nil { return err }
    f, err := os.CreateTemp(dir, ".wtest")
    if err != nil { return err }
    f.Close(); os.Remove(f.Name())
    return nil
}

Try / catch

if err := util.ImportCABundle(caCertPEM, caKeyPEM); err != nil {
    var perr *fs.PathError
    if errors.As(err, &perr) {
        // inspect perr.Path / perr.Err: fix permissions or disk
    }
}

Prevention

When it happens

Trigger: os.WriteFile(caCertPath, ..., 0644) fails — typically because ConfDir does not exist, the workspace/config directory is read-only, or a filesystem/permission error occurs.

Common situations: Workspace on a read-only mount or full disk; running the kernel as a user without write access to the workspace conf directory; ConfDir removed or not yet initialized.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/116a1cb2a417ec24. Report an issue: GitHub.

Appendix: source

Thrown at kernel/util/cert.go:344

	if !caCert.IsCA {
		return fmt.Errorf("the provided certificate is not a CA certificate")
	}

	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

View on GitHub (pinned to 9f775e8a12)