Error Handling
GraphQL handles errors differently from REST APIs. This page explains the error response format and how to handle common scenarios.
Key Difference from REST
GraphQL always returns HTTP 200, even when there are errors. You cannot rely on HTTP status codes to detect failures. Instead, check the response body for an errors array.
A successful HTTP 200 response can still contain errors. Always check both the data and errors fields in the response.
Response Structure
Every GraphQL response can contain two top-level fields:
{
"data": { },
"errors": [ ]
}
| Field | When present |
|---|---|
data | Always present when the query is valid (may contain null values if some fields errored) |
errors | Only present when something went wrong |
There are three possible outcomes:
Success — data only
{
"data": {
"certificate": {
"name": "web-server.example.com",
"status": "ACTIVE"
}
}
}
Total failure — errors only (or data is null)
The query itself was invalid, or authentication failed:
{
"errors": [
{
"message": "Unauthorized",
"extensions": {
"code": "UNAUTHENTICATED"
}
}
]
}
Partial success — both data and errors
Some fields resolved, others failed. GraphQL returns what it can and reports errors for the rest:
{
"data": {
"certificate": {
"name": "web-server.example.com",
"validity": null
}
},
"errors": [
{
"message": "Unable to resolve validity details",
"path": ["certificate", "validity"]
}
]
}
The path field tells you exactly which field in the response errored.
Error Object Format
Each error in the errors array has these fields:
| Field | Description |
|---|---|
message | Human-readable description of the error |
locations | Where in the query string the error occurred (line and column) |
path | The response field path that errored (e.g., ["certificate", "validity"]) |
extensions | Additional metadata, often including an error code |
Common Error Scenarios
Authentication failure
Cause: Missing or invalid tppl-api-key header.
{
"errors": [
{
"message": "Unauthorized",
"extensions": { "code": "UNAUTHENTICATED" }
}
]
}
Fix: Verify your API key is correct and included in the tppl-api-key header.
Invalid query syntax
Cause: Malformed GraphQL (missing braces, typos, etc.).
{
"errors": [
{
"message": "Syntax Error: Expected Name, found \"}\"",
"locations": [{ "line": 3, "column": 1 }]
}
]
}
Fix: Check your query syntax. Use the Interactive Playground for syntax validation as you type.
Unknown field
Cause: Requesting a field that doesn't exist on a type.
{
"errors": [
{
"message": "Cannot query field \"hostname\" on type \"Certificate\". Did you mean \"fingerprint\"?",
"locations": [{ "line": 3, "column": 5 }]
}
]
}
Fix: Check the type reference page for available fields.
Missing required argument
Cause: Omitting a required argument (marked with ! in the schema).
{
"errors": [
{
"message": "Field \"certificate\" argument \"fingerprint\" of type \"ID!\" is required but not provided.",
"locations": [{ "line": 2, "column": 3 }]
}
]
}
Resource not found
Cause: The requested resource doesn't exist.
{
"data": {
"certificate": null
}
}
This is not an error — it's a valid response indicating no certificate exists with that fingerprint. Nullable return types (without !) can return null.
Pagination limits exceeded
Cause: Requesting more items than the maximum page size.
{
"errors": [
{
"message": "Argument \"first\" must be between 1 and 100"
}
]
}
Fix: Keep first and last values at 100 or below. See Pagination.
Handling Errors in Code
Here's a robust error handling pattern:
async function graphqlRequest(query, variables = {}) {
const response = await fetch('https://api.venafi.cloud/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'tppl-api-key': process.env.CM_API_KEY,
},
body: JSON.stringify({ query, variables }),
});
const result = await response.json();
if (result.errors) {
for (const error of result.errors) {
console.error(
`GraphQL error: ${error.message}`,
error.path ? `at path: ${error.path.join('.')}` : ''
);
}
}
return result;
}
Next Steps
- Full Query Reference — All 73 available queries
- Full Mutation Reference — All 75 available mutations
- Interactive Playground — Test queries with real-time error feedback