netbirdio/netbird · error

write signature file (%s): %w

Error message

write signature file (%s): %w

What it means

os.WriteFile failed for the detached root-key signature written next to the public key at the path '<--artifact-pub-key-file>.sig' with mode 0600. This is the last of three writes in handleCreateArtifactKey, so a failure here leaves the priv and pub key files on disk without their signature.

Source

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

		return fmt.Errorf("failed to parse private root key: %w", err)
	}

	artifactKey, privPEM, pubPEM, signature, err := reposign.GenerateArtifactKey(privateRootKey, expiration)
	if err != nil {
		return fmt.Errorf("generate artifact key: %w", err)
	}

	if err := os.WriteFile(artifactPrivKeyFile, privPEM, 0o600); err != nil {
		return fmt.Errorf("write private key file (%s): %w", artifactPrivKeyFile, err)
	}

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

	signatureFile := artifactPubKeyFile + ".sig"
	if err := os.WriteFile(signatureFile, signature, 0o600); err != nil {
		return fmt.Errorf("write signature file (%s): %w", signatureFile, err)
	}

	cmd.Printf("✅ Artifact key created successfully.\n")
	cmd.Printf("%s\n", artifactKey.String())
	return nil
}

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)

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Remove or fix ownership of a stale '<pub>.sig' file (rm/chown) and rerun
  2. Confirm write permission on the whole output directory, since priv, pub, and .sig land side by side
  3. Free disk space if the error reports ENOSPC
Defensive patterns

Strategy: validation

Validate before calling

sigFile := artifactPubKeyFile + ".sig"
if err := os.Remove(sigFile); err != nil && !os.IsNotExist(err) { ... } // clear stale ownership conflicts
os.MkdirAll(filepath.Dir(sigFile), 0o700)

Prevention

When it happens

Trigger: The .sig path being un-writable specifically, e.g. an existing .sig owned by another user or a read-only file at that exact name; disk full after the two key writes; directory made read-only between runs.

Common situations: Rerunning create-artifact-key into a directory where a previous run (possibly as root) left a .sig with different ownership; full disks after large artifacts; immutable/RO mount for secrets.

Related errors


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