Health check endpoint exists, returns HTTP 200, verifies critical dependencies, and consumed by load balancer
Why it matters
A health check endpoint that only returns HTTP 200 without verifying the database or downstream services will report healthy during a database connection pool exhaustion or broken third-party integration — exactly the conditions that cause user-facing failures. NIST SI-6 requires software verification; ISO 25010 reliability.availability requires accurate system state reporting. A load balancer routing traffic to a broken instance that reports itself healthy multiplies the failure, not the resilience. The health endpoint is the contract between your application and its infrastructure.
Severity rationale
Low because a shallow health check returns false positives under partial failures, causing load balancers to route to unhealthy instances rather than triggering failover — the gap is only realized during compound failures.
Remediation
Create an /api/health route that verifies your critical dependencies before returning 200.
// src/app/api/health/route.ts
import { NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';
export async function GET() {
try {
const supabase = createClient();
await supabase.from('_health').select('1').single(); // lightweight DB probe
return NextResponse.json({ status: 'healthy' }, { status: 200 });
} catch (err) {
return NextResponse.json(
{ status: 'unhealthy', error: (err as Error).message },
{ status: 503 }
);
}
}
Then configure your platform to use it:
- AWS ALB: Target Group → Health check path:
/api/health - Kubernetes:
livenessProbe.httpGet.path: /api/health - Vercel: no native load balancer health check, but use Uptime Robot against this endpoint
Detection
-
ID:
health-check -
Severity:
low -
What to look for: Enumerate every relevant item. Look for a health check endpoint (typically at
/health,/api/health,/healthz, or/status). Check if it returns HTTP 200 when healthy. Verify it checks critical dependencies (database connection, external API connectivity). Confirm the load balancer or orchestration platform (Kubernetes, AWS ALB, Vercel) is configured to consume this endpoint. -
Pass criteria: At least 1 of the following conditions is met. A health check endpoint exists at a standard path. It returns HTTP 200 when healthy. It checks critical dependencies. The load balancer or orchestration consumes it.
-
Fail criteria: No health check endpoint found, or endpoint doesn't verify dependencies, or platform isn't configured to use it.
-
Skip (N/A) when: The project doesn't run on a load-balanced platform.
-
Detail on fail:
"No /health endpoint found in application routes."or"/health endpoint exists but only returns 200, does not verify database connectivity."or"Health endpoint exists but load balancer is not configured to use it." -
Remediation: Add a health check endpoint. For Next.js:
// app/api/health/route.ts import { NextResponse } from 'next/server'; export async function GET() { try { // Check database const db = await getDatabase(); await db.query('SELECT 1'); // Check critical external service const response = await fetch('https://api.external-service.com/health', { timeout: 5000 }); if (!response.ok) throw new Error('External API down'); return NextResponse.json({ status: 'healthy' }, { status: 200 }); } catch (error) { return NextResponse.json( { status: 'unhealthy', error: error.message }, { status: 503 } ); } }Then configure load balancer to check this endpoint:
- Vercel: Add health check in vercel.json or dashboard
- AWS ALB: Target group → Health check settings → Path:
/api/health - Kubernetes: Add liveness probe in deployment manifest
External references
- iso-25010:2011 · reliability.availability — Availability — health check enables load balancer to route away from unhealthy instances
- nist:rev5 · SI-6 — Security and Privacy Function Verification
Taxons
History
- 2026-04-18·v1.0.0·Initial import from deployment-readiness·automated