OpenNHP/opennhp · critical

fail to create public key directory

Error message

fail to create public key directory: %w

What it means

generateCosignKeyPair creates the cosign key pair at init time and prepares directories for both key files. This error is returned when os.MkdirAll for the public key's parent directory fails (wrapped as 'fail to create public key directory: %w').

Solutions

  1. Check the wrapped error and grant write permission on the public key's parent directory
  2. Align publicKeyPath with privateKeyPath's directory unless a separate public location is required
  3. Make the key paths configurable via env/config and validated at startup
  4. Pre-create and chown the directory in the deployment image
Defensive patterns

Strategy: validation

Validate before calling

pubDir := filepath.Dir(publicKeyPath)
if err := os.MkdirAll(pubDir, 0755); err != nil {
	return fmt.Errorf("public key dir %s not creatable: %w", pubDir, err)
}
if f, err := os.CreateTemp(pubDir, ".wtest"); err != nil {
	return fmt.Errorf("public 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 public key directory") {
		log.Fatalf("cannot create public key dir %s: %v", filepath.Dir(publicKeyPath), err)
	}
	log.Fatalf("cosign keypair init failed: %v", err)
}

Prevention

When it happens

Trigger: At package init, os.MkdirAll(filepath.Dir(publicKeyPath), 0755) fails because the public key parent directory cannot be created (permissions, read-only fs, path occupied by a file).

Common situations: publicKeyPath set to a directory the service user cannot write; container image with read-only filesystem; divergent private/public key directories where only one is writable; init-time crash loop on startup.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/9f91b745d21a2537. Report an issue: GitHub.

Appendix: source

Thrown at endpoints/server/kbs/resource/resource.go:61

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) {
	path := c.Param("path")
	if path == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "resource path is empty"})
		return

View on GitHub (pinned to 6e04ca5ff0)