numpy.distutils was deprecated in NumPy 1.23 and removed in NumPy 2.0 (June 2024). It also depends on the standard library distutils, which Python 3.12 removed, so it was already unusable on 3.12 regardless of the NumPy version. A setup.py importing it fails with an ImportError during the build, typically inside an isolated build environment where the traceback is buried in pip output.
The replacement for building extensions that need Fortran or BLAS is meson-python, which is what NumPy and SciPy themselves migrated to. For simpler C extensions, plain setuptools with Extension and numpy.get_include() is enough.
The practical trigger is installing an old scientific package from an sdist because no wheel exists for your Python version. Check for a newer release with wheels first; that solves it more often than porting the build. If you must build it, pinning numpy<2 does not help on Python 3.12 because the stdlib dependency is missing, so an older Python is the only route that keeps the original build system.