{"record":{"id":"2780663a607da52b","repo":"netbirdio/netbird","slug":"failed-to-extend-revocation-list-w","errorCode":null,"errorMessage":"failed to extend revocation list: %w","messagePattern":"failed to extend revocation list: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/signer/revocation.go","lineNumber":148,"sourceCode":"\n\trlBytes, err := os.ReadFile(revocationListFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read revocation list file: %w\", err)\n\t}\n\n\trl, err := reposign.ParseRevocationList(rlBytes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse revocation list: %w\", err)\n\t}\n\n\tkid, err := reposign.ParseKeyID(keyID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid key ID: %w\", err)\n\t}\n\n\tnewRLBytes, sigBytes, err := reposign.ExtendRevocationList(*privateRootKey, *rl, kid, expirationDuration)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to extend revocation list: %w\", err)\n\t}\n\n\tif err := writeOutputFiles(revocationListFile, revocationListFile+\".sig\", newRLBytes, sigBytes); err != nil {\n\t\treturn fmt.Errorf(\"failed to write output files: %w\", err)\n\t}\n\n\tcmd.Println(\"✅ Revocation list extended successfully\")\n\treturn nil\n}\n\nfunc handleVerifyRevocationList(cmd *cobra.Command, revocationListFile, signatureFile, publicRootKeyFile string) error {\n\t// Read revocation list file\n\trlBytes, err := os.ReadFile(revocationListFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read revocation list file: %w\", err)\n\t}\n\n\t// Read signature file","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/signer/revocation.go#L130-L166","documentation":"Returned when reposign.ExtendRevocationList fails (client/internal/updater/reposign/revocation.go:181). The function adds the key ID to the parsed RevocationList, stamps LastUpdated and a new ExpiresAt, signs with Ed25519, and json.Marshal's the list and signature. All inputs (root key, list, KeyID) were already validated by earlier steps, so like the create path this wraps internal marshal failures that stock code cannot realistically produce.","triggerScenarios":"extend-revocation-list where reading and parsing all succeeded but json.Marshal of the extended list or the Signature bundle errors — only reachable via a modified reposign package or an anomalous runtime state.","commonSituations":"Nearly unreachable in the field; if seen, it points at a forked/altered reposign (for example an unmarshalable field added to RevocationList) rather than a usage mistake.","solutions":["Read the %w chain to find the failing step (sign vs marshal list vs marshal signature)","Re-run once to rule out a transient fault","Diff client/internal/updater/reposign/revocation.go against upstream and revert local structural changes","Report upstream with the full chain if stock code triggers it"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, _, err := reposign.ExtendRevocationList(*privateRootKey, *rl, kid, expiration); err != nil {\n    // inputs were all validated upstream; treat as internal failure and abort\n    return fmt.Errorf(\"extend revocation list: %w\", err)\n}","preventionTips":["Unit-test any custom reposign fields with json.Marshal round-trips","Do not retry on marshal failures — they are deterministic","Keep the %w chain intact in logs to identify the failing step"],"tags":["go","cli","reposign","json","internal-invariant"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}