FastAPI + ELASTIC_APM_CAPTURE_BODY: Unexpected message received: http.request

Hello! I'm running a FastAPI application (v0.111) with Elastic APM integrated via the elastic-apm package (v6.22.3). The setup had been working smoothly until I modified the APM configuration, setting ELASTIC_APM_CAPTURE_BODY to "all". Following this change, I started encountering the following error:

ERROR: Exception in ASGI application
+ Exception Group Traceback (most recent call last):
| File "/usr/local/lib/python3.12/site-packages/starlette/middleware/base.py", line 192, in __call__
| await response(scope, wrapped_receive, send)
| File "/usr/local/lib/python3.12/site-packages/starlette/responses.py", line 258, in __call__
| async with anyio.create_task_group() as task_group:
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 763, in __aexit__
| raise BaseExceptionGroup(
| ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "/usr/local/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 401, in run_asgi
| result = await app( # type: ignore[func-returns-value]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/usr/local/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
| return await self.app(scope, receive, send)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/usr/local/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
| await super().__call__(scope, receive, send)
| File "/usr/local/lib/python3.12/site-packages/starlette/applications.py", line 123, in __call__
| await self.middleware_stack(scope, receive, send)
| File "/usr/local/lib/python3.12/site-packages/elasticapm/instrumentation/packages/asyncio/starlette.py", line 48, in call
| return await wrapped(*args, **kwargs)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 186, in __call__
| raise exc
| File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 164, in __call__
| await self.app(scope, receive, _send)
| File "/usr/local/lib/python3.12/site-packages/elasticapm/contrib/starlette/__init__.py", line 199, in __call__
| await self.app(scope, _request_receive or receive, wrapped_send)
| File "/usr/local/lib/python3.12/site-packages/starlette/middleware/base.py", line 189, in __call__
| with collapse_excgroups():
| ^^^^^^^^^^^^^^^^^^^^
| File "/usr/local/lib/python3.12/contextlib.py", line 158, in __exit__
| self.gen.throw(value)
| File "/usr/local/lib/python3.12/site-packages/starlette/_utils.py", line 93, in collapse_excgroups
| raise exc
| File "/usr/local/lib/python3.12/site-packages/starlette/responses.py", line 265, in __call__
| await wrap(partial(self.listen_for_disconnect, receive))
| File "/usr/local/lib/python3.12/site-packages/starlette/responses.py", line 261, in wrap
| await func()
| File "/usr/local/lib/python3.12/site-packages/starlette/responses.py", line 238, in listen_for_disconnect
| message = await receive()
| ^^^^^^^^^^^^^^^
| File "/usr/local/lib/python3.12/site-packages/starlette/middleware/base.py", line 58, in wrapped_receive
| raise RuntimeError(f"Unexpected message received: {msg['type']}")
| RuntimeError: Unexpected message received: http.request

This error looks very similar to the issue reported on FastAPI's GitHub (see discussion #10868), which also involves capturing body in the FastAPI middleware.

Does anyone have experience with this or insights into how to resolve it? Specifically, could this be a compatibility issue between the FastAPI version, Starlette, and Elastic APM w

The problem still persists in my application, I would be very grateful for your help.

Looking at your exception it looks like when the apm agent sends all the body we have read inside a message of type http.request , starlette.middleware's _CachedRequest expects to receive an http.disconnect instead because everything has been consumed. I don't see anything obviously wrong on the apm middleware though.

So this is a conflict between starlette.middleware's _CachedRequest and APM middleware? How can I resolve this conflict?