SDK Troubleshooting
Use this guide when traces are not appearing in the Customer Portal, the SDK reports errors, or you are diagnosing an integration problem in production.
Before you start: enable debug logging
The SDK provides verbose logging that shows each export attempt, the batch size, and any errors. Enable it before diagnosing:
# All platforms — set this environment variable
VERIPROOF_DEBUG=trueWith debug logging on, each batch sent to the ingest API is logged with its Merkle root, span count, and HTTP response code.
Trace not appearing in the portal
Work through these checks in order.
1. Verify the SDK is initialized
configure_veriproof (or the equivalent) must be called before any spans are created. If it is called after spans are already being recorded, those earlier spans will not be captured.
# ✅ Correct — configure before any AI calls
configure_veriproof(options, service_name="my-app", set_global=True)
result = await my_ai_function() # This span will be captured
# ❌ Wrong — configure after spans are already being created
result = await my_ai_function() # This span is NOT captured
configure_veriproof(options, service_name="my-app", set_global=True)2. Verify the API key is valid
Test your API key directly against the health endpoint:
curl -X GET https://veriproof-api.rjrlabs.com/health \
-H "X-API-Key: YOUR_SECONDARY_KEY"If the key is invalid, you will receive 401 Unauthorized. Request a replacement from Settings → Security in the Customer Keys panel.
If your code uses a full compound key (vp_cust_...), only pass the last segment (after the final .) to the X-API-Key header when testing with curl. The SDK handles parsing automatically; curl does not.
3. Confirm the application ID matches
The application_id in your SDK configuration must exactly match the Application name registered in the Customer Portal under Applications. A mismatch causes sessions to appear under “Unknown Application” rather than your configured name, but they should still appear.
If no sessions appear at all, the issue is likely the API key, not the application ID.
4. Check the circuit breaker state
If the ingest API was unreachable when the SDK started exporting, the circuit breaker may have opened. Check for circuit breaker log lines:
[VeriProof] Circuit OPEN after 3 consecutive failures. Buffering spans.
[VeriProof] Circuit HALF-OPEN — testing connectivity.
[VeriProof] Circuit CLOSED — resuming normal export.If the circuit is open and the ingest API is now reachable, the circuit will automatically recover after the reset timeout (default: 30 seconds). You do not need to restart your application.
5. Verify spans are completing
OTel spans must close (exit the with block or call end()) before they are exported. A session where the async with session: block never exits — due to an exception or an infinite loop — will not be exported until the span ends.
# ✅ The span closes when the 'async with' block exits
async with session:
await my_ai_function()
# ❌ The span never reaches the exporter if an unhandled exception
# propagates before the 'async with' block exits
async with session:
raise RuntimeError("Unhandled error — span closes but might be marked Error")Authentication errors
| Error | Likely cause | Fix |
|---|---|---|
401 Unauthorized | Invalid or revoked key | Regenerate the key from the portal |
401 Unauthorized | Wrong segment of the compound key | Use only the secondary segment (after last .) in X-API-Key |
403 Forbidden | Sandbox key used on production endpoint without sandbox header | Use a production key for production |
403 Forbidden | Mutation on a sandbox session via a non-sandbox user | Sandbox is read-only for external tenants |
Export / transport errors
422 Unprocessable Entity — Merkle root mismatch
This means the Merkle root computed by the SDK does not match the root the server computed from the same batch. This should not occur in normal operation. Possible causes:
- A custom implementation that computes the Merkle root differently
- A proxy or load balancer modifying the request body
If you see this consistently, contact support with the request ID from the X-Request-Id response header.
429 Too Many Requests — Rate limit exceeded
The SDK respects the Retry-After header automatically. If you are seeing consistent rate limit errors in production, check your plan limits under Settings → Billing and consider batching spans more aggressively or upgrading your plan.
Connection timeout
If your ingest calls time out, check:
- Network egress rules — the ingest API hostname (
veriproof-api.rjrlabs.com) must be reachable on port 443 from your application’s network. - Proxy configuration — if your environment routes outbound HTTPS through a proxy, configure the SDK’s
headersoption with proxy authentication. - DNS resolution —
nslookup veriproof-api.rjrlabs.comshould resolve without errors.
Framework adapter issues
Adapter installed but spans not auto-captured
-
Confirm the adapter is imported/registered before the AI framework is first used:
from veriproof_sdk import configure_veriproof, VeriproofClientOptions from veriproof_sdk_instrumentation_langgraph import instrument_langgraph configure_veriproof(options, service_name="my-app", set_global=True) instrument_langgraph() # Must be called before creating any LangGraph graphs -
For .NET adapters, verify
AddVeriproofTracingis called beforeAddSemanticKernelinIServiceCollectionregistration order.
Duplicate spans (seeing each step twice)
This usually means both a framework adapter and manual session builder calls are recording the same operation. Choose one approach for each span:
- Use the adapter for framework-managed spans (graph nodes, crew tasks, etc.)
- Use the session builder only for spans the adapter does not cover (e.g., custom decision context)
Performance impact
VeriProof should add no measurable latency to your AI calls. If you are seeing increased latency:
- Check if
set_global=Trueis conflicting with anotherTracerProviderthat adds high-latency exporters. VeriProof’s exporter is async and non-blocking — if your existing provider has synchronous exporters, those would be the source. - Check if
enable_content_capture=Trueis adding large span attribute payloads. Turning this off reduces payload size.
Getting further help
If you cannot resolve the issue with this guide:
- Enable debug logging (
VERIPROOF_DEBUG=true) and reproduce the error. - Collect the request ID from the
X-Request-Idresponse header if the error is an HTTP status code. - Contact support at support@veriproof.app with your debug logs and request ID.
Next steps
- SDK Reference — Python — full
VeriproofClientOptionsparameter reference - Environments & API Keys — key formats, scopes, and rotation
- SDK Health Monitoring — monitor SDK export health in production