Skip to content

Error handling

Failures raise. A query that matches nothing is a normal page whose total_results is 0, and cves or matches is empty. Check that attribute. Do not check for None.

NvdClientError
├── InvalidDateFormatError
├── InvalidParametersError
├── InvalidCVEIDError
├── NvdApiError
│   ├── NvdRateLimitError
│   └── NvdNotFoundError
└── NvdResponseError

ValueError is the builtin. NvdConfig raises it for a bad setting. It is not a subclass of NvdClientError.

Exception When it is raised
InvalidCVEIDError The id is not CVE-YYYY-NNNN with at least four digits in the sequence (CVE-YYYY- plus \d{4,}). No request is sent. cve_id is the value that failed.
InvalidDateFormatError A date argument is not a datetime. date_str is the value that failed. If only one end of a range is set, InvalidParametersError is raised first.
InvalidParametersError A date range is incomplete, reversed, or longer than 120 days. per_page or offset is out of range or not an int. A required CPE name, criteria, or match-criteria id is blank. A per-call proxy is blank. missing_params lists the incomplete date pair when that is the reason.
ValueError NvdConfig itself is invalid: base URL, timeout, page-size bounds, a negative retry or backoff setting, or a proxy that is not a string. See Configuration.
NvdNotFoundError HTTP 404, or get_cve_by_id received an empty page. An empty id lookup is still HTTP 200, so status_code is 200 and url is the CVE endpoint. Subclass of NvdApiError.
NvdRateLimitError HTTP 403 or 429 after retries are exhausted. Subclass of NvdApiError. A 403 whose message says the API key is invalid is NvdApiError instead, and it is not retried.
NvdApiError Any other HTTP error, including a rejected API key, and connection or timeout failures after retries.
NvdResponseError The body was not JSON, or it did not match the pydantic model. The HTTP call itself succeeded. This exception has no status_code.

NvdApiError and its subclasses expose status_code and url. status_code is None when the failure happened before a response, for example a timeout or a connection error.

InvalidParametersError, InvalidDateFormatError, and InvalidCVEIDError are raised locally. They do not have status_code.

from nvd_client import NvdApi, NvdNotFoundError, NvdRateLimitError

with NvdApi() as api:
    try:
        record = api.get_cve_by_id("CVE-2024-30078")
    except NvdNotFoundError as exc:
        print(exc.status_code, exc)
    except NvdRateLimitError:
        raise

Which status becomes which error

Response Retried Exception after the last attempt
404 No NvdNotFoundError (status_code 404)
200 with an empty get_cve_by_id page No NvdNotFoundError (status_code 200)
403 or 429, other than a rejected key Yes NvdRateLimitError
403 that reports an invalid API key No NvdApiError
400 and any other 4xx outside the retry list No NvdApiError
500, 502, 503, 504 Yes NvdApiError
Connection error or timeout Yes NvdApiError (status_code is None)
200 whose body is not JSON No NvdResponseError
200 whose JSON does not match the model No NvdResponseError

The retry list is 403, 429, 500, 502, 503, and 504, plus requests connection failures. The message check for a rejected key looks at the message response header and the first 500 characters of the body. It treats the response as a rejected key when that text contains invalid and either api key or apikey.

An empty page from get_all_cves, get_cve_by_date, get_cve_by_cpe, or any CPE Match method is success. total_results == 0.

Attributes

Exception Attributes
InvalidDateFormatError date_str, message
InvalidParametersError missing_params, message
InvalidCVEIDError cve_id, message
NvdApiError, NvdRateLimitError, NvdNotFoundError status_code, url
NvdResponseError the exception message only
ValueError the exception message only

str(InvalidCVEIDError(...)) is {cve_id} -> {message}. str(InvalidDateFormatError(...)) is {date_str} -> {message}. str(InvalidParametersError(...)) names missing_params when that list is non-empty.