{"record":{"id":"b08f545be715eb44","repo":"slackhq/nebula","slug":"errblocklisted","errorCode":"ErrBlockListed","errorMessage":"certificate is in the block list","messagePattern":"certificate is in the block list","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cert/errors.go","lineNumber":14,"sourceCode":"package cert\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nvar (\n\tErrBadFormat                  = errors.New(\"bad wire format\")\n\tErrRootExpired                = errors.New(\"root certificate is expired\")\n\tErrExpired                    = errors.New(\"certificate is expired\")\n\tErrNotCA                      = errors.New(\"certificate is not a CA\")\n\tErrNotSelfSigned              = errors.New(\"certificate is not self-signed\")\n\tErrBlockListed                = errors.New(\"certificate is in the block list\")\n\tErrFingerprintMismatch        = errors.New(\"certificate fingerprint did not match\")\n\tErrSignatureMismatch          = errors.New(\"certificate signature did not match\")\n\tErrInvalidPublicKey           = errors.New(\"invalid public key\")\n\tErrInvalidPrivateKey          = errors.New(\"invalid private key\")\n\tErrPublicPrivateCurveMismatch = errors.New(\"public key does not match private key curve\")\n\tErrPublicPrivateKeyMismatch   = errors.New(\"public key and private key are not a pair\")\n\tErrPrivateKeyEncrypted        = errors.New(\"private key must be decrypted\")\n\tErrCaNotFound                 = errors.New(\"could not find ca for the certificate\")\n\tErrUnknownVersion             = errors.New(\"certificate version unrecognized\")\n\tErrCertPubkeyPresent          = errors.New(\"certificate has unexpected pubkey present\")\n\tErrCurveMismatch              = errors.New(\"certificate curve does not match CA\")\n\n\tErrInvalidPEMBlock                   = errors.New(\"input did not contain a valid PEM encoded block\")\n\tErrInvalidPEMCertificateBanner       = errors.New(\"bytes did not contain a proper certificate banner\")\n\tErrInvalidPEMX25519PublicKeyBanner   = errors.New(\"bytes did not contain a proper X25519 public key banner\")\n\tErrInvalidPEMX25519PrivateKeyBanner  = errors.New(\"bytes did not contain a proper X25519 private key banner\")\n\tErrInvalidPEMEd25519PublicKeyBanner  = errors.New(\"bytes did not contain a proper Ed25519 public key banner\")\n\tErrInvalidPEMEd25519PrivateKeyBanner = errors.New(\"bytes did not contain a proper Ed25519 private key banner\")","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cert/errors.go#L1-L32","documentation":"ErrBlockListed means the certificate's fingerprint (or an alternate fingerprint form, e.g. P256 high-s/low-s variant) is present in the pool's block list. Verification refuses the certificate even if it would otherwise chain to a trusted CA.","triggerScenarios":"verify/VerifyCertificate/VerifyCachedCertificate (cert/ca_pool.go:180, 203) when ncp.IsBlocklisted(fp) or ncp.IsBlocklisted(c.fingerprint2) is true; isInvalidCertificate checks incoming handshake certs against the block list.","commonSituations":"A previously issued certificate/key pair was compromised and revoked by the operator; stale blocklist entries surviving after cert rotation; a node reusing a revoked cert from an old config.","solutions":["Issue a brand-new certificate/key pair for the node and update its config.","Remove the stale entry from the blocklist (ca_pool blocklist data) only if the block was a mistake.","Check whether fingerprint normalization (high-s/low-s P256 forms) is causing an unintended match; compare both fingerprint forms.","Use errors.Is(err, cert.ErrBlockListed) to distinguish revocation from other verification failures."],"exampleFix":"// before\n// node still runs with revoked cert\nvalid, err := pool.VerifyCertificate(oldCert)\n\n// after\nnewPair := reissueCertificate(hostName) // new key material\npool.RemoveBlockedFingerprint(fpOf(oldCert)) // if block was erroneous\nvalid, err := pool.VerifyCertificate(newPair.Cert)","handlingStrategy":"try-catch","validationCode":"fp := hex.EncodeToString(c.Fingerprint)\nif pool.IsBlocklisted(fp) {\n    log.Warn(\"certificate %s is blocklisted — reissue\", c.Name())\n}","typeGuard":"func isBlocked(pool *cert.CAPool, c cert.Certificate) bool {\n    return pool.IsBlocklisted(hex.EncodeToString(c.Fingerprint))\n}","tryCatchPattern":"if _, err := pool.VerifyCertificate(c, fp, \"\"); errors.Is(err, cert.ErrBlockListed) {\n    return fmt.Errorf(\"cert revoked: issue a new keypair for this host\")\n}","preventionTips":["Reissue new key material immediately for any host whose cert was blocklisted.","Audit the blocklist when certs are rotated to avoid stale entries.","Remember alternate fingerprint forms (P256 high-s/low-s) can match the blocklist."],"tags":["certificate","revocation","blocklist"],"backgroundTag":"certificate-revoked","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}