| F01 | Video backend unreachable at session create | Session creation fails; clinician cannot start visit | HTTP 503 from Jitsi health check adapter; VIDEO_PROVIDER_UNAVAILABLE | No session row created; return 503 with diagnostic; clinician may use async visit fallback; ops alert via vcare_backend_health_check_success |
| F02 | Video backend disconnects mid-session (Jitsi server crash) | Participants lose video/audio | Participant disconnect webhook or polling; session status monitor | 60s grace reconnect window; if reconnect fails → transition to failed → notify participants → InitiateFallbackUseCase opens messaging thread |
| F03 | Join token used after expiry | Participant cannot join | 401 TOKEN_EXPIRED from token validator | Return error with link to refresh token; participant calls /join-token for new token |
| F04 | Optimistic lock conflict on session mutation | Second client gets 409 | 409 OPTIMISTIC_LOCK_CONFLICT with currentVersion | Client refetches session and retries; UI handles gracefully |
| F05 | FHIR Gateway unavailable at session end | Encounter not created; billing event delayed | HTTP 5xx from FHIR gateway adapter | Session marked ended with encounterId: null; retry job reconciles within 5 min; alert if unreconciled after 30 min |
| F06 | Recording reference fails to store (Jibri failure) | Recording not available post-session | Jibri webhook failure; recordingRef: null | Session still ends normally; recordingRef null; audit warning; do not block session end |
| F07 | Consent service unavailable at session create | Session creation blocked (fail-closed) | HTTP 5xx from access-policy adapter | Return 503 CONSENT_SERVICE_UNAVAILABLE; do not bypass consent gate; ops alert |
| F08 | Double-end call (race condition) | Concurrent end requests | FSM idempotency on ended state | Second end call on already-ended session returns 200 with current state (idempotent) |
| F09 | Patient network drop during session (intermittent Afghan 3G) | Patient disconnects; session continues for provider | Participant disconnected status via backend webhook | Grace reconnect window applies; if patient reconnects within 60s, session continues; if not, provider can admit again from waiting room or initiate fallback |
| F10 | External provider quota exceeded (Zoom/Webex) | Session creation fails for premium backends | HTTP 503 PROVIDER_QUOTA_EXCEEDED | Return 503; if fallbackVideoBackend configured, auto-retry with secondary; alert ops |
| F11 | Async visit duplicate submission (offline client retries) | Potential duplicate records | clientMutationId unique constraint | DB unique constraint on (tenant_id, client_mutation_id) returns original record; idempotent |
| F12 | NATS JetStream unavailable | Events not published; downstream services miss lifecycle events | Outbox lag alert (> 5 min) | Transactional outbox accumulates events; redelivered when NATS recovers; no event loss |
| F13 | KMS unavailable (cannot sign join token) | Join token issuance fails | KMS API timeout | Return 503; session exists but participants cannot join; ops alert; KMS HA required |
| F14 | AI gateway unavailable during session | STT and summary drafts unavailable | HTTP 5xx from ai-gateway | Degrade gracefully: notify clinician; session continues; manual documentation available |