{"record":{"id":"234dacd0890a9400","repo":"netbirdio/netbird","slug":"failed-to-generate-root-key-w","errorCode":null,"errorMessage":"failed to generate root key: %w","messagePattern":"failed to generate root key: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/signer/rootkey.go","lineNumber":32,"sourceCode":"\tprivKeyFile    string\n\tpubKeyFile     string\n\trootExpiration time.Duration\n)\n\nvar createRootKeyCmd = &cobra.Command{\n\tUse:          \"create-root-key\",\n\tShort:        \"Create a new root key pair\",\n\tLong:         `Create a new root key pair and specify an expiration time for it.`,\n\tSilenceUsage: true,\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t// Validate expiration\n\t\tif rootExpiration <= 0 {\n\t\t\treturn fmt.Errorf(\"--expiration must be a positive duration (e.g., 720h, 365d, 8760h)\")\n\t\t}\n\n\t\t// Run main logic\n\t\tif err := handleGenerateRootKey(cmd, privKeyFile, pubKeyFile, rootExpiration); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to generate root key: %w\", err)\n\t\t}\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n\trootCmd.AddCommand(createRootKeyCmd)\n\tcreateRootKeyCmd.Flags().StringVar(&privKeyFile, \"priv-key-file\", \"\", \"Path to output private key file\")\n\tcreateRootKeyCmd.Flags().StringVar(&pubKeyFile, \"pub-key-file\", \"\", \"Path to output public key file\")\n\tcreateRootKeyCmd.Flags().DurationVar(&rootExpiration, \"expiration\", 0, \"Expiration time for the root key (e.g., 720h,)\")\n\n\tif err := createRootKeyCmd.MarkFlagRequired(\"priv-key-file\"); err != nil {\n\t\tpanic(err)\n\t}\n\tif err := createRootKeyCmd.MarkFlagRequired(\"pub-key-file\"); err != nil {\n\t\tpanic(err)\n\t}\n\tif err := createRootKeyCmd.MarkFlagRequired(\"expiration\"); err != nil {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/signer/rootkey.go#L14-L50","documentation":"Umbrella wrap around handleGenerateRootKey (rootkey.go:31). It covers three distinct inner failures, each self-identifying in the %w chain: 'generate root key: ...' from reposign.GenerateRootKey (entropy or marshal failure), 'write private key file (path): ...' and 'write public key file (path): ...' from the two os.WriteFile calls with 0600 permissions. The dominant real-world cause is one of the writes failing on a missing directory or insufficient permissions.","triggerScenarios":"create-root-key with an output path in a directory that does not exist or is not writable; an existing file at the target owned by another user; in rare cases a system where the entropy source is unavailable so key generation itself fails.","commonSituations":"First-run setup on a new signing host where the key directory was never created; running as non-root against /etc paths; leftover root-owned key files from a previous attempt under a different user.","solutions":["Identify the failing step from the inner message (generate vs write private vs write public)","mkdir -p the parent directories of both --priv-key-file and --pub-key-file","Fix ownership of pre-existing target files or choose fresh paths","If the inner error is 'generate root key', see the entropy guidance for error 359"],"exampleFix":"# before\nsigner create-root-key --priv-key-file /etc/netbird/keys/root.pem --pub-key-file /etc/netbird/keys/root-public.pem --expiration 8760h\n# error: failed to generate root key: write private key file (/etc/netbird/keys/root.pem): open ...: no such file or directory\n\n# after\nmkdir -p /etc/netbird/keys\nsigner create-root-key --priv-key-file /etc/netbird/keys/root.pem --pub-key-file /etc/netbird/keys/root-public.pem --expiration 8760h","handlingStrategy":"validation","validationCode":"func preflightKeygen(priv, pub string) error {\n    for _, p := range []string{priv, pub} {\n        dir := filepath.Dir(p)\n        if _, err := os.Stat(dir); err != nil {\n            return fmt.Errorf(\"output dir %s: %w\", dir, err)\n        }\n        if err := ensureWritableDir(p); err != nil {\n            return err\n        }\n    }\n    return nil\n}\n\n// before create-root-key:\n// err := preflightKeygen(privKeyFile, pubKeyFile)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["mkdir -p both output directories in provisioning scripts","Disambiguate failures via the inner error: write private/public vs generate","Choose fresh output paths per rotation instead of reusing root-owned files"],"tags":["go","cli","file-io","key-management","cobra"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}