A generic 500 response gives users no information about whether the problem is transient or permanent, no way to report what happened, and no confidence that anyone knows the system is broken. CWE-209 warns against exposing internal error details, but the opposite failure — showing nothing at all — is equally problematic for recoverability. ISO 25010 reliability.recoverability requires the system to restore or redirect to a usable state; a 500 page with no retry and no incident ID achieves neither. An incident ID on the error page links user-reported failures to server-side logs without requiring users to paste stack traces.
Low because server errors are less frequent than 404s, but a well-designed 500 page with an incident ID directly reduces support resolution time.
In Next.js App Router, app/error.tsx doubles as the 500 page for server component errors. Surface error.digest as the incident ID — Next.js generates this automatically and logs the correlation server-side.
// app/error.tsx
'use client'
export default function ServerError({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<main style={{ textAlign: 'center', padding: '4rem' }}>
<h1>Something went wrong</h1>
<p>Our team has been notified. Try again or contact support.</p>
{error.digest && <code>Incident ID: {error.digest}</code>}
<button onClick={reset}>Try again</button>
</main>
)
}
Link the support contact to your actual support channel — mailto:support@yourdomain.com or a help URL — not a placeholder.
ID: error-resilience.graceful-degradation-shutdown.server-error-page
Severity: low
What to look for: Count all 500/server error page implementations. Enumerate whether they include retry functionality, user-friendly messaging, and error reporting. Look for a custom 500 page. Check whether it displays an incident ID, tracking reference, or support contact information.
Pass criteria: A custom 500 page exists that displays an incident ID or tracking reference and includes a retry button and support contact link. At least 1 custom server error page must exist with a retry button and user-friendly message.
Fail criteria: No custom 500 page, or 500 page lacks incident ID and support information.
Skip (N/A) when: Never — 500 pages should always be present.
Cross-reference: For 404 page, see not-found-error-page. For error boundary fallbacks, see friendly-fallback-components.
Detail on fail: "No custom 500 page. Default error response shown" or "500 page shows error but no incident ID or support contact"
Remediation: Create an informative 500 page:
// app/error.tsx — custom server error page
'use client'
export default function ServerError({ reset }: { reset: () => void }) { return <div><h1>Server Error</h1><button onClick={reset}>Try Again</button></div> }
// app/error.tsx (in Next.js App Router)
'use client'
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<div style={{ textAlign: 'center', padding: '40px' }}>
<h1>Server Error</h1>
<p>We're sorry, but something went wrong on our end.</p>
{error.digest && (
<p>Error ID: <code>{error.digest}</code> (include this in support messages)</p>
)}
<div style={{ marginTop: '20px' }}>
<button onClick={reset} style={{ marginRight: '10px' }}>
Try Again
</button>
<a href="mailto:support@example.com">Contact Support</a>
</div>
</div>
)
}