It turns out this is a Cloudflare issue. We have Cloudflare acting as a proxy, and intermittently it strips out the Content-Length header (verified in the IIS logs). This is very strange behavior, as it only happens occasionally.
The absence of the Content-Length header causes a failure in the uniGUIISAPI.pas unit of uniGUI, specifically in the PrepareRequest procedure:
SetLength(sBuf, ECB.cbTotalBytes);
System.Move(ECB.lpbData^, sBuf[1], ABytes);
Since the correct size of sBuf cannot be determined, this results in an access violation.
Once I know what to do on the Cloudflare side to address this, I’ll share it here.