Skip to content

Errors

BLOCK and REVIEW are HTTP 200. The JSON decision tells you not to run the action. guard() then raises VulnifyBlockedError. That exception is not an HTTP failure.

The machine contract uses these statuses. The tables on each endpoint page are generated from the spec.

Status Meaning
400 Validation error. For a decision or gateway call, agent or agentId and resource or resourceId are required unless the key is bound to an agent (the agent half). GET /v1/events/{id} uses 400 for a validation error or when the agent or resource was not identified.
401 Missing, invalid, revoked, or expired API key.
403 The key is bound to another agent, or the caller IP is not in the key allowlist. POST /v1/policies/apply also returns 403 when the key is not an org-wide LIVE key.
404 Unknown agent, resource, gateway route, or, on GET, unknown event.
413 JSON body larger than 200 KB. Returned by POST /v1/events, POST /v1/gateway/http, POST /v1/gateway/mcp, POST /v1/policies/apply, and POST /v1/policies/test. GET routes do not return 413.
429 Rate limit exceeded.

A 413 is a client error. The body was rejected before Vulnify evaluated the action. Do not run the action, and do not treat it as an outage.

@vulnify/sdk 0.2.2 and vulnify 0.2.1 raise on every HTTP 4xx except 408 and 429. That includes 400, 401, 403, 404, and 413. failMode: 'open' / fail_mode="open" does not turn those responses into ALLOW. They are not retried. The Node.js fix shipped in 0.2.1 (0.2.0 was not published). The Python fix shipped in 0.2.0.

Node.js throws Error with Vulnify request rejected (STATUS): …. Python raises VulnifyError with the same shape. Python joins a validation message array into one string.

408 is not a status in the OpenAPI document. The SDKs still treat a 408, if one is returned, as transient, along with 429.

For Node.js check() and Python check(), timeouts, network errors, HTTP 408, HTTP 429, and HTTP 5xx are retried. The default is 2 retries, so 3 attempts, all with the same Idempotency-Key. Python waits a short backoff between attempts.

After those attempts, check() returns a local decision and does not throw:

failMode / fail_mode decision degraded id
closed (default) BLOCK true null
open ALLOW true null

reasons[0] starts with Vulnify unavailable and includes the fail mode. degraded: true means Vulnify did not make this decision. A 413 never takes this path.

Node.js getEvent throws on any non-OK status, including 429 and 5xx. It does not retry and it does not apply failMode.

Python get_event and wait_for_review retry the same transient failures as check(), then raise VulnifyError. They do not apply fail_mode.

cURL has no fallback. If the request fails, do not run the action.