Safeguard
Developer Tools•

What should an SDK never include in an error message?

Never put credentials, full request bodies or internal paths in SDK errors. Include a code, status and request ID. Includes a safe error shape and a test.

Safeguard Security Team
4 min read

An SDK error message should never contain credentials, full request or response bodies, personal data, or internal server details such as stack traces and file paths. Give callers a stable error code, the HTTP status, a short human message and a request ID that support can look up.

Why errors leak

Exceptions travel. They get logged by the calling application, sent to an error tracker, pasted into tickets and shown to end users. If your SDK builds its message by dumping the request, anything sensitive in that request goes along for the ride.

MITRE tracks this as CWE-209, generation of an error message containing sensitive information, and the sibling weakness CWE-532, insertion of sensitive information into a log file. The OWASP Error Handling Cheat Sheet shows the defensive pattern: a global handler that returns a generic response for unexpected errors while the details stay in server side logs.

What belongs in an error

IncludeLeave out
Stable machine readable codeAuthorization header or API key
HTTP statusFull request URL if it has a query secret
Short human messageRequest and response bodies
Request ID or trace IDStack traces from your servers
Retry hint, when relevantInternal hostnames, paths, SQL
Link to docs for the codeAnother customer's identifiers

Steps to build a safe error type

  1. Define one error class with fields for code, status, message and request ID. Keep the fields few and stable.
  2. Build the message from templates, never by interpolating the raw request. Parameters that are safe to echo, such as a resource type, can be added one by one.
  3. Strip credentials from any URL before it enters an error. Replace query values with a placeholder.
  4. Keep the raw response body out of the default string form. If callers need it for debugging, expose it as an explicit property they must read on purpose, and document that it may contain sensitive data.
  5. On the server, return the same generic shape for authentication failures whether the user or the password was wrong, so errors do not reveal which accounts exist.
  6. Add a unit test that sets a recognisable fake secret in every input, triggers each error path, and fails if the fake secret appears in the message, the string form or the serialised form.

The validation error trap

Validation errors are the subtle case. Telling a caller that the field named email is not valid is useful. Echoing back the full submitted value is a leak if that value is a password, a token or someone's personal data. Return the field name and the rule that failed, and leave the value out.

Consistency helps defenders too

A stable code per failure lets customers write alerting that does not depend on parsing English. It also lets you change wording without a breaking change, because the code is the contract and the message is a hint. Announce new codes in the changelog so customers can update handlers.

Quick check

Is it ever fine to include the response body in an exception?

As an opt in property, yes, with documentation that it may hold sensitive data. It should not be part of the default message that gets logged automatically.

What is a request ID for?

It lets a customer give support one value that locates the exact request in your logs, so the error message itself can stay short and safe.

Safeguard's policies and gates can check pull requests for risky patterns, and its dependency scanning shows what your SDK pulls in. Try the free scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.