Setting r->discard_body is wrong way to go as it causes lingering timer to be armed on subrequest finalization. Create fake body instead. This also allows to protect real body file from being closed in case it was already read. Though it doesn't matter now as we set r->header_only and relevant code in ngx_http_upstream_send_response() isn't reached.
With r->header_only set upstream module will shutdown client connection in case it needs to do cache/store. Probably it's good idea to avoid setting r->header_only on auth subrequest to make cache work. On the other hand, auth subrequest then will be required to return responses with empty body in all cases, even on errors.