Troubleshooting
Common errors when connecting SDKs to DVARA, with precise fixes. Every error response includes a trace_id — use it to look up the full request in the DVARA Flightdeck audit trail when a single line of error isn't enough.
APIConnectionError — Connection refused
openai.APIConnectionError: Connection error.
Fix: Ensure DVARA is running and accessible at the configured base URL.
curl -sS http://localhost:8080/actuator/health
# expected: {"status":"UP"}
If you're running DVARA in Docker and the SDK from the host, use http://localhost:8080/v1. If both are in the same Docker network, use the service name (e.g. http://dvara:8080/v1).
400 — no_provider
{
"error": {
"code": "no_provider",
"type": "invalid_request_error",
"message": "No provider configured for model: gpt-4o. Set OPENAI_API_KEY to register the provider.",
"trace_id": "..."
}
}
The requested model doesn't match any configured provider. The error message tells you exactly which environment variable to set. For unknown model prefixes you'll see "Check GET /v1/models for available models."
Fix: Set the provider's API key on the DVARA deployment and restart, or register a credential via the DVARA Flightdeck → Credentials page.
401 — Unauthorized
{
"error": {
"code": "invalid_api_key",
"type": "authentication_error",
"message": "Invalid API key",
"trace_id": "..."
}
}
The type is always authentication_error; the code is one of four values so you can grep for the exact reason:
code | Meaning |
|---|---|
api_key_required | No Authorization header was sent and the data plane requires one. |
invalid_api_key | The header was sent but the key didn't match any known hash. |
api_key_revoked | The key matched a row that has been revoked. |
api_key_expired | The key matched a row whose expires_at has passed. |
Fix: Create a new key via the DVARA Flightdeck → API Keys.
Remember: the key you pass to the SDK is the DVARA key (gw_...), not the upstream provider's key.
403 — policy_denied
{
"error": {
"code": "policy_denied",
"type": "policy_violation",
"message": "Request blocked by policy",
"trace_id": "..."
}
}
Fix: A governance policy is blocking the request. Check your workspace's active policies in the DVARA Flightdeck → Policies page, or run the policy in SHADOW mode to see why it denied without blocking the request. See Routes & Policies.
403 — workspace_credential_required
{
"error": {
"code": "workspace_credential_required",
"type": "workspace_credential_required",
"message": "Workspace has no active provider credential",
"trace_id": "..."
}
}
Fix: Strict-BYOK enforcement (dvara.credentials.require-workspace-credential=true) is on and the workspace has no own credential for the upstream provider. Add a workspace-scoped credential in the Portal (/portal/credentials) or have the operator add one from the Console's Credentials page. See Credentials & BYOK.
403 — workspace_suspended
{
"error": {
"code": "workspace_suspended",
"type": "workspace_suspended",
"message": "Workspace has been suspended",
"trace_id": "..."
}
}
That envelope is the LLM plane's. Since 1.7.0 a suspension stops the other two planes as well, and each reports it in its own shape — measured on 1.7.0 against a suspended workspace:
| plane | status | body |
|---|---|---|
LLM (/v1/**) | 403 | the envelope above — lowercase code, a type, a trace_id |
MCP (/mcp/**) | 403 | {"error":{"message":"Workspace is suspended","code":"MCP_WORKSPACE_SUSPENDED"}} — uppercase code, no type, no trace_id |
A2A (/a2a/**) | 403 | a JSON-RPC error: {"jsonrpc":"2.0","id":1,"error":{"code":"A2A_WORKSPACE_SUSPENDED","message":"Workspace is suspended"}} |
Match on the status and the code, not on type — only the LLM plane sets one.
Fix: The workspace is administratively suspended — trial-cliff expiry, chronic-abuse sweep, self-delete schedule, or manual operator action. Cancel the pending deletion (/portal/account/delete/cancel), move to a paid plan, or contact the operator to lift the suspension.
Lifting or applying a suspension is not instantaneous, and the planes do not change together. Workspace records are cached and invalidated through the config-version poller, so there is a propagation window. In one measured run the MCP and A2A planes were refusing within 12 seconds of the database write while the LLM plane was still serving, and the LLM plane caught up before 57 seconds. Expect up to about a minute, and do not read "the LLM plane still answers" in the first few seconds as the suspension having failed.
The WORKSPACE_SUSPENDED_BLOCK audit event is written by the LLM plane only. Blocked MCP tool calls and A2A hops are refused correctly but leave no audit event, so a suspended workspace's blocked agent traffic is not visible in the audit trail. Count refusals from the 403 responses or the plane's own metrics rather than from audit events.
403 — guardrail_blocked
{
"error": {
"code": "guardrail_blocked",
"type": "guardrail_violation",
"message": "Request blocked by guardrail",
"trace_id": "..."
}
}
Fix: A guardrail detector fired at or above the configured risk threshold and the workspace's action is BLOCK. Switch the workspace action to FLAG while you tune patterns, raise the risk threshold, or fix the input. See Guardrails.
400 — pii_detected
{
"error": {
"code": "pii_detected",
"type": "pii_violation",
"message": "Request contains PII",
"trace_id": "..."
}
}
Fix: PII was detected in the request and the workspace's PII action is BLOCK. Switch to REDACT (tokenize and forward) or LOG (forward and record only) per PII detection. Don't disable PII enforcement to "make it work" — investigate the upstream that's leaking PII.
413 — input_too_large
{
"error": {
"code": "input_too_large",
"type": "input_size_error",
"message": "Request exceeds maximum input size",
"trace_id": "..."
}
}
Fix: The request exceeds one of guardrail.max-input-tokens, guardrail.max-messages-per-request, or guardrail.max-message-length (OWASP LLM10 defense). Either reduce the input or raise the per-workspace override (Workspace.metadata["guardrail.max-input-tokens"] etc.) if the workload legitimately needs more.
402 — budget_cap_hard
{
"error": {
"code": "budget_cap_hard",
"type": "budget_exceeded",
"message": "Workspace budget exceeded",
"trace_id": "..."
}
}
Fix: The workspace has hit its hard budget cap. Either raise the cap via the DVARA Flightdeck → Budgets, or wait for the next billing period. The FinOps dashboard shows current spend versus cap.
429 — rate_limit_exceeded
{
"error": {
"code": "rate_limit_exceeded",
"type": "rate_limit_error",
"message": "Rate limit exceeded for this API key",
"trace_id": "..."
}
}
Fix: The API key has hit its configured rate limit. Back off and retry with exponential backoff, or raise the per-key rate limit via the DVARA Flightdeck.
502 — provider_error
{
"error": {
"code": "provider_error",
"type": "provider_error",
"message": "OpenAI API error 401 (invalid API key - check your provider credentials)",
"trace_id": "..."
}
}
Fix: The upstream provider (OpenAI, Anthropic, Bedrock, …) returned an error. The message includes the upstream status code and a hint. DVARA will attempt failover to a configured fallback provider if one is routed. Most common cause: the provider API key configured in DVARA is wrong or revoked — rotate it via Credentials.
503 — provider_circuit_open
{
"error": {
"code": "provider_circuit_open",
"type": "provider_unavailable",
"message": "Provider circuit open",
"trace_id": "..."
}
}
Fix: DVARA's circuit breaker tripped after repeated upstream failures. Wait for the half-open probe to recover, or check the upstream provider's status page. Configure a fallback provider to avoid this failure mode in production.
Where to look next
- Every error includes a
trace_id. Paste it into the DVARA Flightdeck → Audit Trail search to see the full request, which filter rejected it, and the upstream status. - Streaming responses terminate with
finish_reason: "content_filter"on the final chunk when a guardrail fires mid-stream. Inspect the chunk'sfinish_reasonin your stream loop to detect this case (rather than relying on a header — SSE responses don't carry trailing custom headers across all client SDKs). - For policy debugging, enable policy shadow mode: denials still log but requests pass through. See Routes & Policies.
Next steps
- Back to Integrations overview.
- Check out language-specific guides: Python, JavaScript / TypeScript, Java.
- Correlate failures across your stack with DVARA headers.