netbirdio/netbird · warning

at least one --artifact-pub-key-file must be provided

Error message

at least one --artifact-pub-key-file must be provided

What it means

Returned by the signer CLI's bundle-pub-keys cobra command when it is invoked without any --artifact-pub-key-file flags. The command bundles one or more artifact public keys into a package signed by the root private key, so an empty key list is a pure usage error and nothing is executed. It is thrown before any file is read or key is parsed.

Source

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

		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)
		}
		return nil
	},
}

func init() {
	rootCmd.AddCommand(createArtifactKeyCmd)

	createArtifactKeyCmd.Flags().StringVar(&createArtifactKeyRootPrivKeyFile, "root-private-key-file", "", "Path to the root private key file used to sign the artifact key")
	createArtifactKeyCmd.Flags().StringVar(&createArtifactKeyPrivKeyFile, "artifact-priv-key-file", "", "Path where the artifact private key will be saved")
	createArtifactKeyCmd.Flags().StringVar(&createArtifactKeyPubKeyFile, "artifact-pub-key-file", "", "Path where the artifact public key will be saved")
	createArtifactKeyCmd.Flags().DurationVar(&createArtifactKeyExpiration, "expiration", 0, "Expiration duration for the artifact key (e.g., 720h, 365d, 8760h)")

	if err := createArtifactKeyCmd.MarkFlagRequired("root-private-key-file"); err != nil {

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Pass at least one --artifact-pub-key-file <path> (the flag repeats: --artifact-pub-key-file a.pub --artifact-pub-key-file b.pub)
  2. Verify the shell variable holding the key list is non-empty before invoking the command
  3. Check 'bundle-pub-keys --help' to confirm flag spelling and repeatability

Example fix

// before
signer bundle-pub-keys --root-private-key-file root.pem --bundle-pub-key-file bundle.pem
// after
signer bundle-pub-keys --root-private-key-file root.pem --artifact-pub-key-file artifact.pub --bundle-pub-key-file bundle.pem
Defensive patterns

Strategy: validation

Validate before calling

# before calling the CLI
[ ${#PUB_KEY_FILES[@]} -ge 1 ] || { echo "need at least one --artifact-pub-key-file"; exit 1; }
signer bundle-pub-keys --root-private-key-file root.pem "${PUB_KEY_FILES[@]/#/--artifact-pub-key-file }"

Prevention

When it happens

Trigger: Running 'netbird-signer bundle-pub-keys' (or the signer binary's equivalent) with only --root-private-key-file and --bundle-pub-key-file set, omitting every --artifact-pub-key-file occurrence. The flag is a slice, so it is only populated when provided at least once.

Common situations: Scripts that template the flag list and expand to an empty string; CI pipelines where the key list variable is empty; copy-pasting an example command that only shows the required output flags.

Related errors


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