Skip to content

API search returns HTTP 500 when NVD configuration entry is missing nodes #27

Description

@l4rm4nd

Summary

The /api/search/cve endpoint returns 500 Internal Server Error when the result set contains CVEs whose NVD configurations array includes an entry without a nodes field.

FastCVE's Config Pydantic model currently requires nodes to always be present:

class Config(BaseModel):
    class Config:
        extra = Extra.forbid

    operator: Optional[Operator] = None
    negate: Optional[bool] = None
    nodes: List[Node]

When such a CVE is included in a sufficiently large API response, FastAPI response-model validation rejects the entire response.

Environment

  • FastCVE API endpoint: /api/search/cve
  • Query period: 2026-07-11 through 2026-08-12
  • vulnerable=true
  • page-size=3000

Steps to reproduce

Run the following query:

curl --get 'http://127.0.0.1:8000/api/search/cve' \
  --data-urlencode 'pub-start-date=2026-07-11' \
  --data-urlencode 'pub-end-date=2026-08-12' \
  --data-urlencode 'vulnerable=true' \
  --data-urlencode 'page-idx=0' \
  --data-urlencode 'page-size=3000'

Actual result:

HTTP 500
Internal Server Error

The FastCVE container logs show FastAPI response validation failing for two results:

INFO:     172.18.0.16:52224 - "GET /api/search/cve?pub-start-date=2026-07-11&pub-end-date=2026-08-12&vulnerable=true&page-idx=0&page-size=3000 HTTP/1.1" 500 Internal Server Error

ERROR:    Exception in ASGI application

pydantic.error_wrappers.ValidationError: 2 validation errors for CveOutput

response -> result -> 1637 -> configurations -> 0 -> nodes
  field required (type=value_error.missing)

response -> result -> 1638 -> configurations -> 0 -> nodes
  field required (type=value_error.missing)

Root cause

FastCVE's Config model requires every configuration object to contain a nodes array:

class Config(BaseModel):
    class Config:
        extra = Extra.forbid

    operator: Optional[Operator] = None
    negate: Optional[bool] = None
    nodes: List[Node]

However, the stored NVD data for at least two CVEs in this result set contains a configuration object where nodes is absent.

The affected response entries are:

result[1637].configurations[0]
result[1638].configurations[0]

Because nodes is defined as a mandatory field, FastAPI rejects the complete CveOutput response during serialization:

response -> result -> 1637 -> configurations -> 0 -> nodes
field required

response -> result -> 1638 -> configurations -> 0 -> nodes
field required

This means one CVE with a slightly different NVD configuration structure can cause an otherwise valid search containing thousands of CVEs to return HTTP 500.

Expected behavior

The API should return the CVE search results even when an NVD configuration entry does not contain a nodes field.

A missing nodes property should either:

  • be represented as an empty list, or
  • be accepted as an optional field

rather than causing response validation for the entire search result to fail.

Suggested fix

Preferably give nodes an empty-list default:

from pydantic import Field

class Config(BaseModel):
    class Config:
        extra = Extra.forbid

    operator: Optional[Operator] = None
    negate: Optional[bool] = None
    nodes: List[Node] = Field(default_factory=list)

Alternatively, make the property optional:

class Config(BaseModel):
    class Config:
        extra = Extra.forbid

    operator: Optional[Operator] = None
    negate: Optional[bool] = None
    nodes: Optional[List[Node]] = None

Using Field(default_factory=list) may be preferable because consumers of the API can continue treating nodes consistently as an iterable array:

{
  "nodes": []
}

instead of having to handle both arrays and null.

Additional consideration

The NVD CVE schema can evolve or contain records with optional structures that differ from FastCVE's generated Pydantic models.

Strict response validation of externally sourced NVD structures means a single unexpected or omitted property can currently cause the complete /api/search/cve response to fail.

Making optional NVD collection fields tolerant of missing values would make the API more resilient to schema variations and future NVD changes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions