ruvnet/RuView · error · HTTPException
Health check failed: {str(e)}
Error message
Health check failed: {str(e)} What it means
Raised as HTTP 500 by GET /health when any part of the composite health check throws. The handler wraps its whole body in one try/except and embeds the raw exception text in the detail, leaking internals, while the log line 'Health check failed: <e>' carries the same cause. A 500 here almost always means a probed dependency is broken, not that the HTTP app itself is dead.
Source
Thrown at archive/v1/src/api/routers/health.py:186
)
overall_status = "degraded"
# Get system metrics
system_metrics = await asyncio.to_thread(get_system_metrics)
uptime_seconds = (datetime.now() - _APP_START_TIME).total_seconds()
return SystemHealth(
status=overall_status,
timestamp=timestamp,
uptime_seconds=uptime_seconds,
components=components,
system_metrics=system_metrics
)
except Exception as e:
logger.error(f"Health check failed: {e}")
raise HTTPException(
status_code=500,
detail=f"Health check failed: {str(e)}"
)
@router.get("/ready", response_model=ReadinessCheck)
async def readiness_check(request: Request):
"""Check if system is ready to serve requests."""
try:
timestamp = datetime.utcnow()
checks = {}
# Check if services are available in app state
if hasattr(request.app.state, 'pose_service') and request.app.state.pose_service:
try:
checks["pose_ready"] = await request.app.state.pose_service.is_ready()
except Exception as e:
logger.warning(f"Pose service readiness check failed: {e}")View on GitHub (pinned to 4685618388)
Solutions
- Read the server log — the 'Health check failed:' line names the real exception
- Fix the failing dependency (DB URL, network, permissions for metrics)
- If you own the code, catch per-component and return a degraded status instead of letting one probe 500 the whole endpoint (see exampleFix)
- Point liveness probes at a cheaper endpoint (/ready or a root ping) if deep checks are too fragile
Example fix
# before
try:
... # all component checks inline
except Exception as e:
raise HTTPException(500, f'Health check failed: {str(e)}')
# after
components = {}
for name, check in checks.items():
try:
components[name] = check()
except Exception as exc:
components[name] = {'status': 'unhealthy', 'error': type(exc).__name__}
overall = 'unhealthy' if any(c['status'] == 'unhealthy' for c in components.values()) else 'healthy' Defensive patterns
Strategy: fallback
Validate before calling
async def is_healthy(client):
try:
resp = await client.get('/health', timeout=5)
return resp.status_code == 200 and resp.json().get('status') == 'healthy'
except Exception:
return False Try / catch
try:
resp = await client.get('/health', timeout=5.0)
healthy = resp.status_code == 200
except (httpx.HTTPError, asyncio.TimeoutError):
healthy = False
# treat any non-200 (including 500) as unhealthy — never parse the detail text Prevention
- Probe with short timeouts — a slow health check is a failed health check
- Alert on state transitions, not every 500, to avoid storms during dependency outages
- Keep liveness probes cheap; use readiness endpoints for deep dependency checks
When it happens
Trigger: A component probe raises instead of returning a status — the database check throws because the DB is unreachable, a psutil/disk/metrics call fails, or any unexpected exception inside the handler becomes 500 'Health check failed: ...'.
Common situations: Misconfigured DATABASE_URL at deploy time; the process cannot read host metrics inside a minimal container; a downstream dependency is down and the orchestrator polling /health restarts the pod because the endpoint raises instead of reporting degraded.
Related errors
- Failed to get system metrics: {str(e)}
- Unknown service: {service_name}
- An internal error occurred. Please try again later.
- An internal error occurred. Please try again later.
- brain line ${index + 1}: exceeds 16 KiB
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/6ff13d67f00fb7df.
Report an issue: GitHub.