Skip to content

Your First DEFER Verdict in VB-OS

A DEFER verdict means the submitted evidence does not satisfy all boundary conditions. The action should not proceed.

DEFER is not an error: it is a valid evaluation result. It means the verification engine examined the evidence, applied the boundary, and determined that the conditions for authorization are not met.

A DEFER can occur at any of the three pipeline stages. Here is an example where Stage 3 (predicate evaluation) fails:

from vbos import VBOSClient
client = VBOSClient(api_key="YOUR_API_KEY_HERE")
result = client.verify(
workload={
"transaction_amount": 75000,
"account_balance": 42000,
"risk_score": 35
},
project="my-project",
boundary_ref="payment-authorization",
)
print(result.decision) # "DEFER"
print(result.failure_reasons) # Structured list of failures

The failure_reasons array contains structured objects that identify exactly what failed and why.

{
"decision": "DEFER",
"failure_reasons": [
{
"type": "predicate_failed",
"field": "sufficient_funds",
"reason": "Predicate evaluated to false",
"expression": "account_balance >= transaction_amount",
"actual": { "account_balance": 42000, "transaction_amount": 75000 }
},
{
"type": "predicate_failed",
"field": "amount_within_limit",
"reason": "Predicate evaluated to false",
"expression": "transaction_amount <= 50000",
"actual": { "transaction_amount": 75000 }
}
]
}

Two predicates failed:

  • sufficient_funds: 42000 >= 75000 → false (insufficient balance)
  • amount_within_limit: 75000 <= 50000 → false (exceeds per-transaction limit)

The third predicate (risk_acceptable: 35 <= 75) passed, but since predicates are conjunctive, the overall result is DEFER.

Occurs when a required evidence field is missing or null.

{
"decision": "DEFER",
"admissibility": {
"status": "not_satisfied",
"required": ["transaction_amount", "account_balance", "risk_score"],
"present": ["transaction_amount"],
"missing": ["account_balance", "risk_score"]
},
"failure_reasons": [
{
"type": "admissibility_not_satisfied",
"field": "account_balance",
"reason": "Required evidence field is missing"
},
{
"type": "admissibility_not_satisfied",
"field": "risk_score",
"reason": "Required evidence field is missing"
}
]
}

When admissibility fails, the pipeline short-circuits. Stages 2 and 3 do not run. The predicate_results field will be empty or absent.

Occurs when a prohibited evidence field is present in the workload.

{
"decision": "DEFER",
"prohibitions": {
"status": "detected",
"prohibited": ["social_security_number"],
"detected": ["social_security_number"]
},
"failure_reasons": [
{
"type": "prohibited_evidence_present",
"field": "social_security_number",
"reason": "Prohibited evidence field is present"
}
]
}

When a prohibition is violated, the pipeline short-circuits after Stage 2. Stage 3 does not run.

Occurs when one or more named predicates evaluate to false.

{
"failure_reasons": [
{
"type": "predicate_failed",
"field": "sufficient_funds",
"reason": "Predicate evaluated to false",
"expression": "account_balance >= transaction_amount",
"actual": { "account_balance": 42000, "transaction_amount": 75000 }
}
]
}

All predicates are still evaluated (no short-circuit within Stage 3): all failing predicates appear in failure_reasons.

A DEFER verdict:

  • Is recorded as an immutable evaluation record, just like ASSERT
  • Has its own evaluation_id and replay_id
  • Can be replayed from stored artifacts
  • Is a legitimate, expected outcome: not a system failure

Your application should handle DEFER as a normal code path, not an exception. The system did exactly what it was asked to do: evaluate the evidence and report that the conditions were not met.

VB-OS is fail-closed by design:

  • Missing evidence → DEFER (not a best guess)
  • Integrity check failure → evaluation halted (not degraded)
  • Unknown field in workload → ignored (does not affect evaluation)

If the boundary cannot determine that the action should proceed, it does not proceed.