diff --git a/.github/workflows/test-everything.yml b/.github/workflows/test-everything.yml
index e34bff1f3b34eebf0448113029b0154e1ea66ef3..7e9467ee873d8d15978c327d6b4665603521c65b 100644
--- a/.github/workflows/test-everything.yml
+++ b/.github/workflows/test-everything.yml
@@ -19,7 +19,7 @@ jobs:
             cc:    "gcc-8",
             cxx:   "g++-8",
             py:    "3.7",
-            cmake: "3.18.x",
+            cmake: "3.19.x",
             mpi:   "ON",
             simd:  "OFF"
           }
@@ -29,7 +29,7 @@ jobs:
             cc:    "clang-8",
             cxx:   "clang++-8",
             py:    "3.7",
-            cmake: "3.18.x",
+            cmake: "3.19.x",
             mpi:   "ON",
             simd:  "OFF"
           }
@@ -39,7 +39,7 @@ jobs:
             cc:    "clang",
             cxx:   "clang++",
             py:    "3.7",
-            cmake: "3.18.x",
+            cmake: "3.19.x",
             mpi:   "ON",
             simd:  "OFF"
           }
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4d74fa0f77603377f7afe5c989e13ce7249e3281..c3c1c85ef22704cbadb86d175702feab4b91eee0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.18)
+cmake_minimum_required(VERSION 3.19)
 include(CMakeDependentOption)
 
 # Make CUDA support throw errors if architectures remain unclear
diff --git a/doc/install/build_install.rst b/doc/install/build_install.rst
index e426fac28a1da3b6358052a2ee72ccbb5f8a0a98..1f1e721fc24d451b60adbdde4942fc4432ae1eb1 100644
--- a/doc/install/build_install.rst
+++ b/doc/install/build_install.rst
@@ -605,6 +605,20 @@ on your target system that are not covered here, please make an issue on the
 Arbor `Github issues <https://github.com/arbor-sim/arbor/issues>`_ page.
 We will do our best to help you directly, and update this guide to help other users.
 
+.. warn::
+
+   On many HPC systems a tool called ``module`` or ``ml`` is installed, which
+   use the ``CPATH`` environment variable to set up include paths for building.
+   The contents of this variable are forced on all compilations and by extension
+   to dependency generation. This can lead to the wrong headers being picked up
+   despite ``CMake`` reporting the correct versions, which can produce spurious
+   errors.
+
+   If you are using one of these tools (and possibly ```easybuid``) and encounter
+   such problems, try to ``module unload`` as many modules as possibe. One example
+   has been found with JSC clusters and an outdated pybind11 which was brought in
+   by ``ml SciPy-Stack``.
+
 .. _install-mpi:
 
 MPI
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index fd4b68e53b394e1baac328e030bbb35ef40efecd..61f789eef9f2148300a153bace5da0693b94cd80 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -16,7 +16,7 @@ if(ARB_USE_BUNDLED_PYBIND11)
   # instead of using find_package.
   add_subdirectory(${pb11_src_dir} pybind11)
 else()
-  find_package(pybind11 REQUIRED)
+  find_package(pybind11 2.8.1 REQUIRED)
 endif()
 
 set(pyarb_source
diff --git a/python/config.cpp b/python/config.cpp
index efe50545edb5d0d0ab711225bdb0734c1e22c75b..6f8ae58eea26a190d6adc926365a31cce0d97765 100644
--- a/python/config.cpp
+++ b/python/config.cpp
@@ -52,6 +52,16 @@ pybind11::dict config() {
     dict[pybind11::str("version")] = pybind11::str(ARB_VERSION);
     dict[pybind11::str("source")]  = pybind11::str(ARB_SOURCE_ID);
     dict[pybind11::str("arch")]    = pybind11::str(ARB_ARCH);
+    {
+#define mk_tok(x) #x
+#define mk_ver(M, m, p) mk_tok(M) "." mk_tok(m) "." mk_tok(p)
+        const char* version = mk_ver(PYBIND11_VERSION_MAJOR,
+                                     PYBIND11_VERSION_MINOR,
+                                     PYBIND11_VERSION_PATCH);
+        dict[pybind11::str("pybind-version")] = pybind11::str(version);
+#undef mk_ver
+#undef mk_tok
+    }
     return dict;
 }
 
diff --git a/python/pyarb.hpp b/python/pyarb.hpp
index 6678f5904a7a35cc710727f7de01071e208415b8..954195a4396ed3ccc7af40ea9843dfdec2fb3f53 100644
--- a/python/pyarb.hpp
+++ b/python/pyarb.hpp
@@ -13,6 +13,18 @@
 
 #include <pybind11/pybind11.h>
 
+// Version check
+#define mk_tok(x) #x
+#define mk_ver(M, m, p) mk_tok(M) "." mk_tok(m) "." mk_tok(p)
+#define PB11_ERR(M, m, p) "Required version of pybind11 is 2.8.1 <= version < 3.0.0 Found " mk_ver(M, m, p)
+static_assert((PYBIND11_VERSION_HEX >= 0x02080100)
+              &&
+              (PYBIND11_VERSION_HEX  < 0x03000000),
+              PB11_ERR(PYBIND11_VERSION_MAJOR, PYBIND11_VERSION_MINOR, PYBIND11_VERSION_PATCH));
+#undef PB11_ERR
+#undef mk_ver
+#undef mk_tok
+
 namespace pyarb {
 
 // Sample recorder object interface.
diff --git a/spack/package.py b/spack/package.py
index 38047359f92cf345926d60caee3f4312b57313d5..1a998936cd6b4e6c2f6ce1c76a04ed0a138d8d0f 100644
--- a/spack/package.py
+++ b/spack/package.py
@@ -59,7 +59,7 @@ class Arbor(CMakePackage, CudaPackage):
     conflicts("%cce@:9.1")
     conflicts("%intel")
 
-    depends_on("cmake@3.12:", type="build")
+    depends_on("cmake@3.19:", type="build")
 
     # misc dependencies
     depends_on("fmt@7.1:", when="@0.5.3:")  # required by the modcc compiler