{"record":{"id":"61ca670e7fcccaec","repo":"netbirdio/netbird","slug":"failed-to-sign-artifact-w","errorCode":null,"errorMessage":"failed to sign artifact: %w","messagePattern":"failed to sign artifact: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/signer/artifactsign.go","lineNumber":38,"sourceCode":"\tverifyArtifactPubKeyFile    string\n\tverifyArtifactFile          string\n\tverifyArtifactSignatureFile string\n\n\tverifyArtifactKeyPubKeyFile     string\n\tverifyArtifactKeyRootPubKeyFile string\n\tverifyArtifactKeySignatureFile  string\n\tverifyArtifactKeyRevocationFile string\n)\n\nvar signArtifactCmd = &cobra.Command{\n\tUse:   \"sign-artifact\",\n\tShort: \"Sign an artifact using an artifact private key\",\n\tLong: `Sign a software artifact (e.g., update bundle or binary) using the artifact's private key.\nThis command produces a detached signature that can be verified using the corresponding artifact public key.`,\n\tSilenceUsage: true,\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tif err := handleSignArtifact(cmd, signArtifactPrivKeyFile, signArtifactArtifactFile); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to sign artifact: %w\", err)\n\t\t}\n\t\treturn nil\n\t},\n}\n\nvar verifyArtifactCmd = &cobra.Command{\n\tUse:          \"verify-artifact\",\n\tShort:        \"Verify an artifact signature using an artifact public key\",\n\tLong:         `Verify a software artifact signature using the artifact's public key.`,\n\tSilenceUsage: true,\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tif err := handleVerifyArtifact(cmd, verifyArtifactPubKeyFile, verifyArtifactFile, verifyArtifactSignatureFile); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to verify artifact: %w\", err)\n\t\t}\n\t\treturn nil\n\t},\n}\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/signer/artifactsign.go#L20-L56","documentation":"Generic wrapper from the sign-artifact RunE around handleSignArtifact. It wraps one of: reading the artifact private key (env or file), ParseArtifactKey PEM failures, reading --artifact-file, or reposign.SignData errors such as 'artifact length must be positive, got 0' (empty artifact) and 'artifact key expired at ...'.","triggerScenarios":"Signing with an expired artifact key; signing a zero-byte artifact file; missing key file without NB_ARTIFACT_PRIV_KEY set; malformed key PEM; unreadable artifact path.","commonSituations":"Release pipelines that sign after the artifact key's planned lifetime; an empty build output passed to --artifact-file; key sourced from a secret env var that was not injected into the job.","solutions":["Read the chained cause after 'failed to sign artifact:' and address that specific failure","If 'artifact key expired', mint a fresh key with create-artifact-key and re-sign","If 'artifact length must be positive', fix the build so the artifact file is non-empty before signing","Provide the key via NB_ARTIFACT_PRIV_KEY or a valid --artifact-key-file"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// In release scripts: refuse to sign empty artifacts and expired keys first\n[ -s \"$ARTIFACT\" ] || { echo \"artifact is empty\"; exit 1; }\n[ -n \"${NB_ARTIFACT_PRIV_KEY:-}\" ] || [ -r \"$KEY_FILE\" ] || { echo \"no signing key\"; exit 1; }","typeGuard":null,"tryCatchPattern":"err := signArtifactCmd.Execute()\nif err != nil {\n    msg := err.Error()\n    switch {\n    case strings.Contains(msg, \"expired\"):\n        // rotate artifact key, then re-sign\n    case strings.Contains(msg, \"length must be positive\"):\n        // fix the build producing an empty artifact\n    default:\n        log.Fatalf(\"sign-artifact failed: %v\", err)\n    }\n}","preventionTips":["Check artifact file size > 0 before signing","Track artifact key expiry and rotate before it lapses","Inject the key via CI secret (NB_ARTIFACT_PRIV_KEY) and assert it is non-empty at job start"],"tags":["cli","signing","error-wrapping","go"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}