{"record":{"id":"46e225a21567cad0","repo":"netbirdio/netbird","slug":"generate-root-key-w","errorCode":null,"errorMessage":"generate root key: %w","messagePattern":"generate root key: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/signer/rootkey.go","lineNumber":58,"sourceCode":"\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 {\n\t\tpanic(err)\n\t}\n}\n\nfunc handleGenerateRootKey(cmd *cobra.Command, privKeyFile, pubKeyFile string, expiration time.Duration) error {\n\trk, privPEM, pubPEM, err := reposign.GenerateRootKey(expiration)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"generate root key: %w\", err)\n\t}\n\n\t// Write private key\n\tif err := os.WriteFile(privKeyFile, privPEM, 0o600); err != nil {\n\t\treturn fmt.Errorf(\"write private key file (%s): %w\", privKeyFile, err)\n\t}\n\n\t// Write public key\n\tif err := os.WriteFile(pubKeyFile, pubPEM, 0o600); err != nil {\n\t\treturn fmt.Errorf(\"write public key file (%s): %w\", pubKeyFile, err)\n\t}\n\n\tcmd.Printf(\"%s\\n\\n\", rk.String())\n\tcmd.Printf(\"✅ Root key pair generated successfully.\\n\")\n\treturn nil\n}\n","sourceCodeStart":40,"sourceCodeEnd":75,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/signer/rootkey.go#L40-L75","documentation":"reposign.GenerateRootKey failed (root.go:50). The function generates an Ed25519 keypair via ed25519.GenerateKey(rand.Reader), embeds metadata (ID from SHA-256 of the public key, timestamps), and PEM-encodes two JSON blobs. The only realistic failure is the crypto/rand read: the system entropy source (/dev/urandom) is unavailable or exhausted. The json.Marshal steps handle plain structs and cannot realistically fail.","triggerScenarios":"create-root-key running in a restricted container or chroot where /dev/urandom is not mounted; severe entropy starvation during early boot of a VM; otherwise practically unreachable.","commonSituations":"Minimal Docker images with an empty /dev; sandboxed CI runners restricting device access; embedded hosts early in boot before the CRNG initializes.","solutions":["Check the entropy device: ls -l /dev/urandom and cat a few bytes to confirm it is readable","Restart the process or host — transient early-boot starvation resolves once the kernel CRNG is ready","For containers, ensure /dev/urandom is mounted (it is bind-mounted by default in standard runtimes); fix the runtime config if it was removed","If the error is a marshal message instead of a rand error, treat it as a code bug and inspect local modifications to reposign"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"func entropyAvailable() error {\n    f, err := os.Open(\"/dev/urandom\")\n    if err != nil {\n        return fmt.Errorf(\"entropy source unavailable: %w\", err)\n    }\n    defer f.Close()\n    buf := make([]byte, 8)\n    if _, err := io.ReadFull(f, buf); err != nil {\n        return fmt.Errorf(\"entropy read failed: %w\", err)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"var rk *reposign.RootKey\nvar privPEM, pubPEM []byte\nerr := retry(3, 100*time.Millisecond, func() error {\n    rk, privPEM, pubPEM, err = reposign.GenerateRootKey(expiration)\n    return err\n})\nif err != nil {\n    // entropy or environment problem: surface it, do not fabricate a key\n    return fmt.Errorf(\"generate root key: %w\", err)\n}","preventionTips":["Ensure /dev/urandom exists and is readable in containers and chroots","Retry a bounded number of times — early-boot entropy starvation is transient","Never fall back to a weak or fixed key source when rand.Reader fails"],"tags":["go","cli","ed25519","entropy","crypto"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}