Skip to content
On this pageThe error envelopeProxy URL codesHTTP API codesCodes both returnSDK codes

Reference / Errors

Errors

Every error the guard returns carries a code you can branch on. Find yours in the lists below, or link to it with /docs/errors#code.

On a proxy error, read guard-status first. guard-status: not_forwarded means this request did not leave the proxy. It does not say whether an earlier send paid, so follow the entry for the code before you re-sign.

warning

Never resend a payment that answered duplicate_payment or decision_already_used. Check the decision and your wallet first. decision_already_used means it paid. After duplicate_payment, sign a new payment only once this one has expired and no transfer shows.

The error envelope

The API and the proxy URL answer an error the same way. The body holds a code and a message that names the cause and the next step.

An error from the proxy URL
HTTP/1.1 409 Conflict
guard-status: not_forwarded
guard-decision-id: 7c0e1f52-3b8a-4d2e-9a61-0f4c2d8b5e17

{
  "error": {
    "code": "decision_mode_changed",
    "message": "This payment was checked in observe mode before enforcement was enabled. Nothing was forwarded. Request a fresh quote and sign a new payment under the agent's current mode."
  }
}

A proxy error that belongs to a decision also carries guard-decision-id. The SDK throws each API error as a GuardApiError with its code and status. When the SDK hook blocks a payment, it throws a plain Error with no code, and its message gives the reason. The SDK page shows how to handle it.

The MCP tool is advisory. The agent chooses whether to ask. For a check it cannot skip, use the proxy URL or the SDK hook. The advisory MCP server calls the same API, and most of its tool errors name the guard's code and status.

Proxy URL codes

Only the proxy URL returns these.

CodeHTTPLaneCauseNext step
bad_402502Proxy URLThe seller's 402 carries no x402 v2 payment terms the proxy can read.Ask the seller for an x402 v2 quote.
bad_merchant_url400Proxy URLThe seller URL after the token is missing or malformed. Or it is not https, carries a username or password, names a port, points at a private address, runs over 2,000 characters, or sits on this site outside /merchant/.Put a public https seller URL after the token, without its scheme. Pay a seller on your own machine through the SDK.
bad_required_mode400Proxy URLx-vulsight-require-mode carries a value other than enforce.Send enforce, or leave the header out.
content_check_failed503Proxy URLThe guard could not save the check of an answer the agent read from this seller, so the payment was not forwarded.Send the payment again shortly.
content_check_pending503Proxy URLA page or 402 the agent read from this seller is still being checked, so the payment was not forwarded.Send the payment again after the seconds in retry-after.
decision_unavailable503Proxy URLThe proxy decided the payment but could not reach its database before forwarding it.Send the payment again after retry-after. If that answer carries a new guard-decision-id, follow that one. If it answers duplicate_payment, follow that entry.
duplicate_payment409Proxy URLThe proxy already decided this signed payment, and another send of it may have reached the seller.Do not send it again. Check your wallet and the decision in guard-decision-id. Sign a new payment only once this one has expired and no transfer shows. If the answer has no guard-decision-id, a newer signed payment took over; follow that payment's answer.
key_in_request400Proxy URLThe request carries a VulSight API key or proxy token in Authorization.Remove it. The token in the URL is all the proxy needs, and the seller must not see your key.
legacy_offer_unbound409Proxy URLA decision saved by an older release does not name the exact seller offer.Wait for that decision to expire, then start a new payment.
legacy_payer_unbound409Proxy URLA review saved by an older release has no verified payer.Check that decision and your wallet. Wait for it to expire before you start a new payment.
merchant_answer_cut502Proxy URLThe seller stopped part way through its answer, so none of it was passed on.Read the message before you ask again. On a paid request it says whether the payment settled.
merchant_answer_invalid502Proxy URLThe seller answered in a form the proxy cannot pass on, such as a status outside 200 to 599.Read the message before you ask again. On a paid request it says whether the payment settled.
merchant_answer_too_large502Proxy URLThe seller's answer is larger than the 4 MiB the proxy relays.Ask the seller for a smaller resource. On a paid request, the message says whether the payment settled.
merchant_answer_too_slow504Proxy URLThe seller sent its headers, but its body did not finish in the time the proxy waits.Read the message before you ask again. On a paid request it says whether the payment settled.
merchant_unreachable502, 504Proxy URLThe seller could not be reached (502), did not answer in time (504), or the proxy had too little time left to forward the payment.Check the URL and try again. With guard-status: not_forwarded, re-sign and send it again. With a guard-decision-id only, read that decision before you pay again.
no_challenge400Proxy URLThe proxy has no 402 on file for this URL.Request the URL through the proxy first, then send the payment. If the seller redirects before it asks for payment, request it with redirect: "manual" and pay theLocation.
payment_denied403Proxy URLThe policy denied the payment, or its review was denied or expired. guard-status says which.Read the reasons in the message and on the decision in decisionId. The reason codes say what each one means.
redirected_after_payment409Proxy URLThe first payment reached the seller, which redirected to a URL that asks for payment again. No second payment was sent.Check the first payment's decision on Decisions. Then pay the proxy URL the message names if you still need it.
relay_budget_exceeded429Proxy URLThis answer would take the account past the 256 MiB of seller answers the proxy relays in a UTC day. No payment was forwarded.Try again after midnight UTC. retry-after counts down to it.
resign_required402, 409Proxy URLThe signed payment expired, or came too close to expiring, before the proxy could forward it.Request the URL again for a fresh quote and sign that. guard-next-step reads fresh_quote.
review_pending402Proxy URLThe payment is held for a person, and the review was still open when the proxy answered.Approve it on Review, then send the payment again after retry-after, signed again if it has expired. The same review answers it.
revoked_proxy_token401Proxy URLThe proxy token was revoked.Create a new key on the Keys page and put its proxy token in the URL.
sign_in_code_check_unavailable503Proxy URLThe URL carries token, and the proxy could not check whether it is a password reset code for this site.Try again in a few seconds.
sign_in_code_in_url400Proxy URLThe link carries a sign-in or password reset code for this site.Do not use the link again. Sign in or reset your password on this site. An agent calls the proxy URL from a fetch client, not a browser page load.
solana_rpc_unavailable503Proxy URLThe proxy could not check the Solana blockhash before forwarding.Request a fresh quote and try again in a minute.
unknown_proxy_token401Proxy URLThe token is not recognized or was rotated. An API key (vs_test_) in the URL gets this code too.Put the proxy token (vsp_test_) from the Keys page in the URL. If an API key was in a URL, rotate it on Keys.
unreadable_payment400Proxy URLThe proxy cannot read or pay the PAYMENT-SIGNATURE header. The message names the cause.Have the client pick a supported payment from the seller's 402, or ask the seller for one.
x402_v1400Proxy URLThe payment came in an X-PAYMENT header. The proxy URL takes x402 v2 only.Send the payment in PAYMENT-SIGNATURE.

HTTP API codes

The HTTP API is advisory. Your code acts on its answer.

CodeHTTPLaneCauseNext step
admin_required403HTTP APIThe content history routes are for administrators only.View your content checks in the dashboard.
idempotency_conflict409HTTP APIThis Idempotency-Key was already used for a different payment.Send a new key for a new payment, or the same body to read that decision again.
invalid_cursor422HTTP APIThe before and beforeId of a content history call do not form a page cursor.Send both values from the previous page's next.
invalid_request422HTTP APIThe body, the query, x-vulsight-channel or Idempotency-Key is wrong. The message names the first bad field.Fix that field and send the request again.
method_not_allowed405HTTP APIThe route does not take that method.Send it again with a method the allow header names.
missing_api_key401HTTP APINo Authorization header was sent, or its value is empty, such as Bearer undefined or Bearer null.Send the key as a Bearer token, and check that the variable holding it is set.
not_found404HTTP APINo decision, or content request, with that id belongs to your account.Check the id, and that the key belongs to the account that made it.
proxy_not_paired403HTTP APIThe proxy token in x-vulsight-proxy-token and the API key do not belong to the same active agent.Send the key and proxy token the Keys page showed together for one agent.
revoked_api_key401HTTP APIThe key was revoked.Create a new key on the Keys page.
settlement_conflict409HTTP APIAnother decision in your account already carries this transaction in this direction. The message names it.Report the payment on that decision, or send the hash of the transfer that settled this one.
settlement_limit409HTTP APIThe decision already holds eight settlements in this direction.Make a decision for the payment this transfer settled, and report it there.
settlement_mismatch409HTTP APIThe decision approved no payment, or the report's payee, amount, asset, network or payer differ from it. The message names the field.Report the payment as the decision approved it, on the decision that allowed or approved it.
unknown_api_key401HTTP APIThe key is mistyped or was rotated, or a proxy token (vsp_test_) was sent as the key.Check it for a stray character. Send the API key (vs_test_) the Keys page showed when it was made or rotated.
unknown_route404HTTP APINo API route answers at that path. The message lists the routes.Check the path. The API lives under /api/v1.

Codes both return

The HTTP API and the proxy URL both return these.

CodeHTTPLaneCauseNext step
bad_request400HTTP API and proxy URLOn the API, /api/v1/status or /api/healthz was called with a query string or a variant of its path. On the proxy URL, the request carries something that cannot be sent as written. The message names it.Call the exact path with no query. On the proxy URL, remove what the message names and send it again.
content_history_unavailable503HTTP API and proxy URLThe guard could not save text for checking. On the proxy URL the seller may already have answered, and when an answer was held back the message says so.Send it again. If the request changes something on the seller, check whether it took effect before you send it again.
decision_already_used409HTTP API and proxy URLThis decision already paid. Its settlement is on file.Do not pay for it again. To buy again, use a new Idempotency-Key on the API, or request a fresh quote and sign a new payment on the proxy URL.
decision_mode_changed409HTTP API and proxy URLThe decision was made in observe mode, and the agent now enforces its policy. It would have been denied or held.Start a new payment attempt. Use a new Idempotency-Key on the API, or a fresh quote and a new signature on the proxy URL.
decision_not_finalized409HTTP API and proxy URLThe guard has no record that this decision finished its budget check, so it cannot be reused.Start a new payment attempt. On the proxy URL, request a fresh quote and sign again.
internal500HTTP API and proxy URLSomething failed on the guard's side. On the proxy URL, a paid request may or may not have reached the seller.After a paid request, read the agent's latest decision on Decisions before you send it again. Otherwise try again.
payment_screening_unavailable503, 504HTTP API and proxy URLWallet screening could not finish (504 when the proxy ran out of time). The message starts with the cause when it is known.Send it again once screening recovers, after the retry-after seconds when the answer has them. If the message says to sign a new payment, do that.
proxy_not_enforced409HTTP API and proxy URLThe agent is in observe mode, and preflight or x-vulsight-require-mode: enforce asked for enforce.Switch the agent to enforce in the Mode card on Policy. On the proxy URL you can instead leave x-vulsight-require-mode out.
rate_limited429HTTP API and proxy URLToo many calls this minute, or the account has sent its 16 MiB of text for checking this UTC day. The message names the limit.Wait the seconds in retry-after, then send it again. The limits are in the rate limit table.
request_timeout408HTTP API and proxy URLThe request body did not finish arriving in time.Send a smaller body or use a faster connection, then send it again.
request_too_large413HTTP API and proxy URLThe body is over 1 MiB on the API, or over the 4 MiB the proxy relays.Send a smaller body.

SDK codes

The SDK throws these itself when the guard's base URL does not answer as the guard.

CodeHTTPLaneCauseNext step
http_errorAnySDKThe base URL answered without the guard's error envelope.Check baseUrl or VULSIGHT_BASE_URL. On a 408, 429 or 5xx, try again in a moment.
redirected3xxSDKThe guard's base URL answered with a redirect, and the SDK does not carry the key through one.Set baseUrl or VULSIGHT_BASE_URL to the address the message names.