OpenNHP/opennhp · critical
fail to create private key directory
Error message
fail to create private key directory: %w
What it means
generateCosignKeyPair creates the cosign key pair at init time and prepares the directories for the private and public key files. This error is returned when os.MkdirAll for the private key's parent directory fails (wrapped as 'fail to create private key directory: %w').
Solutions
- Check the wrapped error for EACCES/EROFS and fix filesystem permissions or mount
- Verify privateKeyPath (private key dir env/config) points to a writable location
- Run the daemon as a user with write access to the target directory
- Pre-create the directory in the deployment image and give it proper ownership
Example fix
// before
if err := os.MkdirAll(filepath.Dir(privateKeyPath), 0755); err != nil {
return fmt.Errorf("fail to create private key directory: %w", err)
}
// after (configurable, validated path)
keyDir := os.Getenv("KBS_KEY_DIR")
if keyDir == "" {
keyDir = defaultKeyDir
}
if err := os.MkdirAll(keyDir, 0700); err != nil {
return fmt.Errorf("fail to create private key directory %s: %w", keyDir, err)
} Defensive patterns
Strategy: validation
Validate before calling
keyDir := filepath.Dir(privateKeyPath)
if fi, err := os.Stat(keyDir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists and is not a directory", keyDir)
}
if err := os.MkdirAll(keyDir, 0755); err != nil {
return err
}
if f, err := os.CreateTemp(keyDir, ".wtest"); err != nil {
return fmt.Errorf("key dir not writable: %w", err)
} else {
f.Close(); os.Remove(f.Name())
} Try / catch
if err := generateCosignKeyPair(); err != nil {
if strings.Contains(err.Error(), "fail to create private key directory") {
log.Fatalf("cannot create key dir, check permissions/read-only fs: %v", err)
}
log.Fatalf("cosign keypair init failed: %v", err)
} Prevention
- Configure key paths to a writable volume (not the read-only image rootfs)
- Run the daemon with a user that owns the key directory
- Smoke-test directory writability in the deployment script before launch
- Never point privateKeyPath at a path occupied by an existing file
When it happens
Trigger: At package init, filepath.Dir(privateKeyPath) cannot be created — parent path is an existing file, permission denied, or a read-only filesystem.
Common situations: Deploying nhp-server with a read-only rootfs; privateKeyPath configured under a directory owned by another user; running the daemon without the required user in Docker; a typo making the dir path collide with an existing file.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- fail to create public key directory
- fail to write private key file
- fail to write public key file
- resource not found
- could not get file info
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/46c8d50439d73277.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/server/kbs/resource/resource.go:57
if err != nil {
panic(err)
}
}
func generateCosignKeyPair(privateKeyPath, publicKeyPath string) error {
if _, err := os.Stat(privateKeyPath); err == nil {
if _, err := os.Stat(publicKeyPath); err == nil {
return nil
}
}
keys, err := cosign.GenerateKeyPair(nil)
if err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(privateKeyPath), 0755); err != nil {
return fmt.Errorf("fail to create private key directory: %w", err)
}
if err := os.MkdirAll(filepath.Dir(publicKeyPath), 0755); err != nil {
return fmt.Errorf("fail to create public key directory: %w", err)
}
if err := os.WriteFile(privateKeyPath, keys.PrivateBytes, 0600); err != nil {
return fmt.Errorf("fail to write private key file: %w", err)
}
if err := os.WriteFile(publicKeyPath, keys.PublicBytes, 0644); err != nil { //nolint:gosec // G306: Public keys are intentionally world-readable
return fmt.Errorf("fail to write public key file: %w", err)
}
return nil
}
func GetResource(c *gin.Context) {View on GitHub (pinned to 6e04ca5ff0)