netbirdio/netbird · error

read public key file: %w

Error message

read public key file: %w

What it means

os.ReadFile failed on one of the --artifact-pub-key-file entries while looping over the list in handleBundlePubKeys. Note the message does not include the offending pubFile name, so correlate by position/count when multiple files are passed.

Source

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

func handleBundlePubKeys(cmd *cobra.Command, rootPrivKeyFile string, artifactPubKeyFiles []string, bundlePubKeysFile string) error {
	cmd.Println("📦 Bundling public keys into signed package...")

	privKeyPEM, err := os.ReadFile(rootPrivKeyFile)
	if err != nil {
		return fmt.Errorf("read root private key file: %w", err)
	}

	privateRootKey, err := reposign.ParseRootKey(privKeyPEM)
	if err != nil {
		return fmt.Errorf("failed to parse private root key: %w", err)
	}

	publicKeys := make([]reposign.PublicKey, 0, len(artifactPubKeyFiles))
	for _, pubFile := range artifactPubKeyFiles {
		pubPem, err := os.ReadFile(pubFile)
		if err != nil {
			return fmt.Errorf("read public key file: %w", err)
		}

		pk, err := reposign.ParseArtifactPubKey(pubPem)
		if err != nil {
			return fmt.Errorf("failed to parse artifact key: %w", err)
		}
		publicKeys = append(publicKeys, pk)
	}

	parsedKeys, signature, err := reposign.BundleArtifactKeys(privateRootKey, publicKeys)
	if err != nil {
		return fmt.Errorf("bundle artifact keys: %w", err)
	}

	if err := os.WriteFile(bundlePubKeysFile, parsedKeys, 0o600); err != nil {
		return fmt.Errorf("write public keys file (%s): %w", bundlePubKeysFile, err)
	}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Iterate the same file list and stat each path before rerunning to find the missing one
  2. Quote globs and guard empty variables in the invoking script
  3. Confirm each entry is a readable regular file

Example fix

// before (script)
for f in $PUB_KEYS; do ... done  # empty/typo entries slip through silently
// after
for f in $PUB_KEYS; do [ -r "$f" ] || { echo "missing: $f"; exit 1; }; done
Defensive patterns

Strategy: validation

Validate before calling

for _, f := range artifactPubKeyFiles {
    info, err := os.Stat(f)
    if err != nil || info.IsDir() {
        log.Fatalf("artifact public key not readable: %s", f)
    }
}

Prevention

When it happens

Trigger: Any entry in the repeated --artifact-pub-key-file list that does not exist or is unreadable; a trailing empty string from an unquoted, non-expanded shell variable; a directory passed instead of a file.

Common situations: Glob that matched nothing ('*.pub' unexpanded); typos in one of many paths; CI checkout missing one key artifact.

Related errors


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