@if ($recovered) The Kulibri health check on {{ $host }} is passing again. @else The Kulibri health check on {{ $host }} is FAILING. A real login -> fetch polls -> logout round trip against the live system did not complete. Users are likely affected. @endif Checked at: {{ $result['checked_at'] ?? 'unknown' }} Total time: {{ $result['duration_ms'] ?? '?' }} ms Steps: @forelse (($result['checks'] ?? []) as $name => $check) - {{ str_pad($name, 8) }} {{ strtoupper($check['status']) }}@if (isset($check['duration_ms'])) ({{ $check['duration_ms'] }} ms)@endif @if (isset($check['error'])) -- {!! $check['error'] !!}@endif @if (isset($check['polls'])) -- {{ $check['polls'] }} poll(s) returned @endif @empty - (no steps ran) @endforelse What the steps mean: - logs a log write threw. Usually storage/logs owned by the wrong user, or a full disk. Every endpoint that logs (LoggerMiddleware, PollController) returns 500 while this is broken, so users are affected, not just this check. Fix: chown -R www-data:www-data storage bootstrap/cache - config the HEALTH_CHECK_* env values are missing on this server - login POST /api/login; 422 means wrong credentials, 500 means the app threw - polls GET /api/polls; 403 means the monitoring user is not email-verified, "expected at least N poll(s)" means the database is up but empty/wrong - logout POST /api/logout; cleanup of the throw-away token Full result: {{-- Unescaped on purpose: this is a plain-text mail, so Blade's HTML escaping would turn every quote in the JSON into ". The content is generated by HealthCheckService, not user input. --}} {!! json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) !!} -- Sent once when the check starts failing and once when it recovers, not on every failed run. See Hosting.md for setup and troubleshooting.