{"record":{"id":"2f1dc214297a93d0","repo":"netbirdio/netbird","slug":"artifact-private-key-must-be-provided-via-s-envir","errorCode":null,"errorMessage":"artifact private key must be provided via %s environment variable or --artifact-key-file flag","messagePattern":"artifact private key must be provided via (.+?) environment variable or --artifact-key-file flag","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/cmd/signer/artifactsign.go","lineNumber":131,"sourceCode":"\nfunc handleSignArtifact(cmd *cobra.Command, privKeyFile, artifactFile string) error {\n\tcmd.Println(\"🖋️  Signing artifact...\")\n\n\t// Load private key from env var or file\n\tvar privKeyPEM []byte\n\tvar err error\n\n\tif envKey := os.Getenv(envArtifactPrivateKey); envKey != \"\" {\n\t\t// Use key from environment variable\n\t\tprivKeyPEM = []byte(envKey)\n\t} else if privKeyFile != \"\" {\n\t\t// Fall back to file\n\t\tprivKeyPEM, err = os.ReadFile(privKeyFile)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"read private key file: %w\", err)\n\t\t}\n\t} else {\n\t\treturn fmt.Errorf(\"artifact private key must be provided via %s environment variable or --artifact-key-file flag\", envArtifactPrivateKey)\n\t}\n\n\tprivateKey, err := reposign.ParseArtifactKey(privKeyPEM)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse artifact private key: %w\", err)\n\t}\n\n\tartifactData, err := os.ReadFile(artifactFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read artifact file: %w\", err)\n\t}\n\n\tsignature, err := reposign.SignData(privateKey, artifactData)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"sign artifact: %w\", err)\n\t}\n\n\tsigFile := artifactFile + \".sig\"","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/signer/artifactsign.go#L113-L149","documentation":"sign-artifact found no artifact private key: the NB_ARTIFACT_PRIV_KEY environment variable is empty/unset AND --artifact-key-file is empty. This is a pure configuration error raised before any file or cryptographic operation.","triggerScenarios":"Invoking sign-artifact with only --artifact-file; setting the env var to an empty string (which counts as unset in this code path); CI secret not injected so NB_ARTIFACT_PRIV_KEY is missing from the environment.","commonSituations":"CI job where the signing secret was not configured or renamed; local shell where the export was forgotten; secret injected as empty after masking.","solutions":["Pass --artifact-key-file <path> to the artifact private key from create-artifact-key","Or export NB_ARTIFACT_PRIV_KEY containing the PEM (single-line-friendly secret) in CI","Verify the secret injection: print ${#NB_ARTIFACT_PRIV_KEY} (length only, never the value)"],"exampleFix":"# before\nsign-artifact --artifact-file app.tar.gz\n# after\nNB_ARTIFACT_PRIV_KEY=\"$KEY_PEM\" sign-artifact --artifact-file app.tar.gz\n# or\nsign-artifact --artifact-key-file artifact.key --artifact-file app.tar.gz","handlingStrategy":"validation","validationCode":"const envArtifactPrivateKey = \"NB_ARTIFACT_PRIV_KEY\"\nhasKey := os.Getenv(envArtifactPrivateKey) != \"\" || privKeyFile != \"\"\nif !hasKey {\n    return fmt.Errorf(\"configure %s or --artifact-key-file before signing\", envArtifactPrivateKey)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Assert the CI secret is injected by checking its length, never its value","Document one canonical way to supply the key (env secret) and stick to it","Fail job setup early on missing secrets rather than mid-signing"],"tags":["cli","configuration","signing","ci","go"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}