netbirdio/netbird · error
generate artifact key: %w
Error message
generate artifact key: %w
What it means
reposign.GenerateArtifactKey failed while creating a new artifact signing key signed by the root key. Its concrete failures are: the root key has expired (checked against rootKey.Metadata.ExpiresAt), ed25519 key generation errors (rare), PEM marshalling of the new key, or signing the key metadata with the root key.
Source
Thrown at client/cmd/signer/artifactkey.go:112
}
}
func handleCreateArtifactKey(cmd *cobra.Command, rootPrivKeyFile, artifactPrivKeyFile, artifactPubKeyFile string, expiration time.Duration) error {
cmd.Println("Creating new artifact signing key...")
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)
}
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 nilView on GitHub (pinned to 93e97f4bf1)
Solutions
- Check the chained message; if it says 'root key has expired', generate a new root with create-root-key and re-sign artifact keys
- Verify the system date/time (timedatectl or equivalent) if the key should still be valid
- If it is a marshal/sign error, re-export or regenerate the root key, since the key material is likely corrupted
Defensive patterns
Strategy: validation
Validate before calling
// Before generating artifact keys, ensure the root key is still valid
rootKey, err := reposign.ParseRootKey(privKeyPEM)
if err != nil { ... }
if time.Now().After(rootKey.Metadata.ExpiresAt) {
return fmt.Errorf("rotate root key first: expired on %s", rootKey.Metadata.ExpiresAt.Format(time.RFC3339))
} Prevention
- Alert on root key expiration well before the date (calendar/monitoring)
- Create root keys with a lifetime longer than the planned artifact key rotation cycle
- Keep NTP enabled on signing hosts to avoid clock-induced expiry
When it happens
Trigger: Invoking create-artifact-key with a root key whose ExpiresAt is in the past; a corrupted root key whose embedded metadata fails to serialize/sign. The overwhelming majority of real hits are the expired-root-key branch, which reports 'root key has expired on <RFC3339>'.
Common situations: Reusing a root key past its planned lifetime (default root keys are often created with bounded expiration); system clock skew making a valid root key look expired.
Related errors
- bundle artifact keys: %w
- --expiration must be a positive duration (e.g., 720h, 365d,
- failed to create artifact key: %w
- at least one --artifact-pub-key-file must be provided
- failed to bundle public keys: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/471c8ef5194eb75c.
Report an issue: GitHub.