Safeguard
Security Guides•

Do your error messages leak internals? An error handling review guide

Return a generic message to users, log the details server side, use one global handler and watch 5xx rates. A short code review guide for error handling.

Safeguard Security Team
3 min read

Users should see a generic error message, and the details should go to your server logs. In review, check that stack traces, SQL errors and file paths never reach the response, that a global handler covers unexpected failures, and that status codes are used correctly.

What the guidance says

The OWASP Error Handling Cheat Sheet recommends returning a generic message to the user, with content that does not reveal implementation details, and recording full details on the server for investigation. It also recommends one catch-all error handler configured in the runtime or in code, so unexpected errors are handled the same way everywhere.

The reason is reconnaissance. Error output can expose framework names and versions, file paths and SQL errors, which help an attacker find injection points and known weaknesses.

What to look for in a diff

PatternWhy it matters
Returning the exception message in the response bodyLeaks internals
Debug mode flags enabled in a shared configDetailed pages in production
A try block that swallows errors silentlyFailures go unnoticed
Different messages for unknown user and wrong passwordReveals which accounts exist
New endpoint with its own error formatBypasses the global handler

Status codes carry signal

The cheat sheet advises 4xx for errors caused by the client and 5xx for server failures the application cannot fulfill, and suggests monitoring 5xx rates because they can signal problems with certain inputs. A reviewer can use that: if a change turns validation failures into 500 responses, you lose a clean signal and may hide a crash that someone can trigger on purpose.

Steps for a review

  1. Find every place the diff builds a response from an exception. Check what text is included.
  2. Check that the full error, with identifiers to correlate, is logged server side.
  3. Look for a global handler. If the framework provides one, confirm the new code does not bypass it.
  4. Compare messages for related failures, such as login failures, so they do not leak account existence.
  5. Ask for a test that triggers an error and asserts the response has no stack trace or path.
// risky
res.status(500).send(err.stack);

// safer
logger.error({ err, requestId });
res.status(500).json({ message: "Something went wrong", requestId });

Returning a request ID lets support find the log entry without exposing anything.

What the source does not say

The cheat sheet does not describe a fail closed rule. That is a common design principle for security checks, and worth applying in authorization code, but treat it as team guidance and not as something this page requires.

Where Safeguard fits

Safeguard scans dependencies and builds SBOMs, so framework versions with known error handling issues show up in your inventory. Try the free scan at gold.safeguard.sh/scan.

Quick check

Why not show users the real error?

Detailed errors expose framework versions, paths and SQL errors that help attackers. Log them server side instead.

Why watch 5xx rates?

OWASP notes they can signal problems with certain inputs, including crafted ones.

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.