{"record":{"id":"53af7c30e861f7b9","repo":"netbirdio/netbird","slug":"read-root-key-file-w","errorCode":null,"errorMessage":"read root key file: %w","messagePattern":"read root key file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/signer/artifactsign.go","lineNumber":214,"sourceCode":"\tcmd.Printf(\"Artifact: %s\\n\", artifactFile)\n\tcmd.Printf(\"Signed by key: %s\\n\", signature.KeyID)\n\tcmd.Printf(\"Signature timestamp: %s\\n\", signature.Timestamp.Format(\"2006-01-02 15:04:05 MST\"))\n\treturn nil\n}\n\nfunc handleVerifyArtifactKey(cmd *cobra.Command, artifactKeyFile, rootKeyFile, signatureFile, revocationFile string) error {\n\tcmd.Println(\"🔍 Verifying artifact key...\")\n\n\t// Read artifact key data\n\tartifactKeyData, err := os.ReadFile(artifactKeyFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read artifact key file: %w\", err)\n\t}\n\n\t// Read root public key(s)\n\trootKeyData, err := os.ReadFile(rootKeyFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read root key file: %w\", err)\n\t}\n\n\trootPublicKeys, err := parseRootPublicKeys(rootKeyData)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse root public key(s): %w\", err)\n\t}\n\n\t// Read signature\n\tsigBytes, err := os.ReadFile(signatureFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read signature file: %w\", err)\n\t}\n\n\tsignature, err := reposign.ParseSignature(sigBytes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse signature: %w\", err)\n\t}\n","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/signer/artifactsign.go#L196-L232","documentation":"os.ReadFile on the --root-key-file path failed during verify-artifact-key. This flag takes the root public key PEM used to validate the artifact key's root signature. Same *fs.PathError causes as other reads: missing file, permission, directory.","triggerScenarios":"Root public key not provisioned on the verifying machine; wrong path in the CI config; passing the private root key path when only the public one exists locally.","commonSituations":"Root public keys live in the embedded certs directory in production; verifiers forget to fetch them; path differs between environments.","solutions":["ls -l the exact --root-key-file value; use the ROOT PUBLIC KEY PEM from generate-root-key","Copy the root public key from the trusted key store before running verify-artifact-key","Check read permissions on the file"],"exampleFix":"// before\nreturn fmt.Errorf(\"read root key file: %w\", err)\n\n// after\nreturn fmt.Errorf(\"read root key file %s: %w\", rootKeyFile, err)","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(rootKeyFile); err != nil {\n    log.Fatalf(\"root public key %s not readable: %v\", rootKeyFile, err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provision the current root public keys on verifier machines as part of setup","Track root key generation explicitly during rotations so the right PEM is used"],"tags":["go","cli","filesystem","release-signing"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}