Start with the response that actually failed
Record method, path, time, authentication state, status, content type and any correlation identifier. Remove credentials and confidential content from shared evidence. Check whether the response comes from the application, a gateway or an upstream service. An HTML error page in front of a JSON API may explain why the client cannot read the result.
In browsers, a CORS problem can prevent access to a response that actually exists. A timeout, by contrast, leaves it unclear whether the server-side action has already occurred. Do not blindly repeat a write request; retries and idempotency covers uncertain outcomes.
Distinguish status codes by meaning
The following selection helps with security and data-contract questions. The normative basis is RFC 9110, sections 15.5 and 15.6. It is not a list of every possible API error.
On narrow screens, scroll the table sideways.
| Status | Meaning for interpretation | Useful next step |
|---|---|---|
400 Bad Request | The request is not processed because of a perceived client error, such as malformed syntax | Check format, required information and the specific API contract |
401 Unauthorized | Valid authentication credentials for the target resource are missing; the server must send an appropriate WWW-Authenticate challenge | Check the credential used, token type and validity; do not copy secrets into error logs |
403 Forbidden | The server understands and refuses the request; the reason need not concern credentials | Check the documented reason and required permission; do not automatically repeat the same unchanged request |
404 Not Found | No current representation was found, or its existence is not disclosed | Check the path and intended visibility; do not conclude with certainty that the object does not exist |
405 Method Not Allowed | The known method is unsupported for this resource; the response must contain Allow | Compare the method with the specific resource contract |
409 Conflict | Conflict with the resource's current state | Check state again and resolve the business conflict |
413 Content Too Large | The request content exceeds the accepted size | Adjust its size to documented limits |
415 Unsupported Media Type | The content format is unsupported for this method and resource | Compare actual content, Content-Type and, where applicable, Content-Encoding |
422 Unprocessable Content | The content type is understood and syntax correct, but the contained instructions cannot be processed | Evaluate understandable business error details |
5xx | A server error prevents intended processing | Use protected operational diagnostics; retry only under an appropriate contract |
‘401 means signed out, 403 means signed in’ is too narrow as a general rule: RFC 9110 explicitly allows 403 reasons independent of credentials. OAuth bearer errors have additional rules under the protocol profile used. A 404 may conceal a forbidden resource's existence. Choose this visibility deliberately and consistently; response content and other observable differences may also disclose information.
429 Too Many Requests concerns request limiting and is defined in RFC 6585, section 4. Optional Retry-After helps decide when to wait, but does not prove effective limits across every flow. See rate limits.
Problem Details standardises the error body
If clients need machine-readable additional information, RFC 9457 offers the Problem Details format. It replaces RFC 7807. The format is one possible shared agreement; not every API must replace its existing domain-specific error contract. RFC 9457, sections 1 and 4.
The following synthetic example describes a date order disallowed by business rules. The address under .invalid is explicitly an unreachable example; a real API should choose a stable problem type identifier under its own control.
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
Cache-Control: no-store
{
"type": "https://api.example.invalid/problems/invalid-date-range",
"title": "Invalid date range",
"status": 422,
"detail": "The end date must be on or after the start date.",
"instance": "urn:uuid:17ce8990-26ec-4dad-a379-472107807b05",
"errors": [
{ "pointer": "/end_date", "code": "before_start" }
]
}
type identifies the problem type, title names it briefly, detail helps with the specific case and instance identifies this occurrence. The errors entry defined here is a custom extension; its fields are not a universal contract for all Problem Details APIs. A stable identifier suits client decisions better than parsing a translated explanatory sentence.
If the producer includes status, it must use the same code as the actual HTTP status. A 200 with "status": 422 in the body is not equivalent: proxies, caches and general HTTP clients use the HTTP status. The shown no-store is a deliberate cache decision for this example, not a blanket RFC requirement for every problem response. RFC 9457, section 3.1.
Provide corrective guidance instead of debug data
A validation response may, for example, state that a public field has an invalid value. It should contain no SQL statements, internal file paths, stack traces, tokens or complete customer records. A link to a detailed error instance also needs suitable access protection. A hard-to-guess correlation identifier is not itself authorisation.
Internal diagnostics may include cause category, affected service, safe metadata and an identifier. The client receives only its intended subset. Limit and sanitise internal records too; a protected log does not justify permanently recording every secret and request body. RFC 9457, section 5, OWASP Error Handling.
A global error handler helps with unexpected exceptions. Expected error cases also need understandable responses. Check parsers, authentication, routers, proxies and downstream services too: they may fail before your handler is reached. CORS and content-type rules must remain consistent in each required response context.
Check response and side effect together
In an isolated environment, deliberately generate known errors with your own synthetic data: missing credentials, missing permission, invalid time range, an unknown test path of your own and controlled failure of a test dependency. Compare status, headers and body with the agreed contract. For an unexpected exception, check that the client receives a bounded error and the responsible operator receives a correlatable diagnostic entry.
For rejected changes, additionally check stored data and any jobs. An error message after unauthorised storage has already occurred is not successful evidence of authorisation. Keep legitimate older clients in mind during format changes. Safe rollback preserves correct statuses and limits on internal details, even if it initially returns to the previous error format.
What an API Security Check error finding means
The public check examines a limited GET error path and looks in analysable responses for selected patterns, such as stack traces, database errors, internal paths or debug hints. This subcheck stops on 401 or 403. Responses that cannot be fully or meaningfully analysed must be read with their measurement limitation.
A match is a signal to assess against the actual response. It does not prove exploitable injection or complete compromise. Without a match, other error paths, authenticated flows and write operations remain untested. The check does not validate a complete Problem Details contract either.
For headers, Allow and assessment limits, see reading HTTP findings. Logging and monitoring explains the operational side; testing your own API security connects error behaviour and business safeguards.
Sources and date
Sources checked: 27 September 2026. Links also appear alongside the statements they support.