netbirdio/netbird · error

failed to create artifact key: %w

Error message

failed to create artifact key: %w

What it means

The create-artifact-key workflow failed after flag validation: reading the root private key file, parsing it with reposign.ParseRootKey, generating the artifact key pair, or writing the three outputs (private key, public key, .sig). The %w chain names the failing step.

Source

Thrown at client/cmd/signer/artifactkey.go:36

	createArtifactKeyRootPrivKeyFile string
	createArtifactKeyPrivKeyFile     string
	createArtifactKeyPubKeyFile      string
	createArtifactKeyExpiration      time.Duration
)

var createArtifactKeyCmd = &cobra.Command{
	Use:   "create-artifact-key",
	Short: "Create a new artifact signing key",
	Long: `Generate a new artifact signing key pair signed by the root private key.
The artifact key will be used to sign software artifacts/updates.`,
	SilenceUsage: true,
	RunE: func(cmd *cobra.Command, args []string) error {
		if createArtifactKeyExpiration <= 0 {
			return fmt.Errorf("--expiration must be a positive duration (e.g., 720h, 365d, 8760h)")
		}

		if err := handleCreateArtifactKey(cmd, createArtifactKeyRootPrivKeyFile, createArtifactKeyPrivKeyFile, createArtifactKeyPubKeyFile, createArtifactKeyExpiration); err != nil {
			return fmt.Errorf("failed to create artifact key: %w", err)
		}
		return nil
	},
}

var bundlePubKeysCmd = &cobra.Command{
	Use:   "bundle-pub-keys",
	Short: "Bundle multiple artifact public keys into a signed package",
	Long: `Bundle one or more artifact public keys into a signed package using the root private key.
This command is typically used to distribute or authorize a set of valid artifact signing keys.`,
	RunE: func(cmd *cobra.Command, args []string) error {
		if len(bundlePubKeysPubKeyFiles) == 0 {
			return fmt.Errorf("at least one --artifact-pub-key-file must be provided")
		}

		if err := handleBundlePubKeys(cmd, bundlePubKeysRootPrivKeyFile, bundlePubKeysPubKeyFiles, bundlePubKeysFile); err != nil {
			return fmt.Errorf("failed to bundle public keys: %w", err)
		}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Verify each path exists and is readable: ls -l on all --*-file arguments
  2. mkdir -p the output directories before running
  3. Confirm the root private key was produced by the matching create-root-key command and is the expected key type
  4. Read the wrapped step text ('read root private key file', 'failed to parse private root key', 'write ... file') to target the fix
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(rootPrivKeyFile); err != nil {
	return fmt.Errorf("root private key %s unreadable: %w", rootPrivKeyFile, err)
}
for _, out := range []string{artifactPrivKeyFile, artifactPubKeyFile} {
	if err := os.MkdirAll(filepath.Dir(out), 0o700); err != nil {
		return err
	}
}

Try / catch

if err := handleCreateArtifactKey(cmd, root, priv, pub, exp); err != nil {
	// the wrap names the step: read/parse/generate/write; fix that input before retrying
	return fmt.Errorf("failed to create artifact key: %w", err)
}

Prevention

When it happens

Trigger: --root-private-key-file missing or unreadable; the file is not a valid root key PEM (wrong key or corrupted); output directories do not exist or are unwritable; disk full while writing key files.

Common situations: Pointing at the public instead of the private root key; running the signer in CI where output directories were never created; key files copied between machines with broken permissions.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/0ca49496e04eca65. Report an issue: GitHub.