diff --git a/pre_commit/clientlib.py b/pre_commit/clientlib.py
index 77b92d4..2f16650 100644
--- a/pre_commit/clientlib.py
+++ b/pre_commit/clientlib.py
@@ -13,6 +13,7 @@ from identify.identify import ALL_TAGS
 import pre_commit.constants as C
 from pre_commit.error_handler import FatalError
 from pre_commit.languages.all import all_languages
+from pre_commit.util import parse_version
 
 
 def check_type_tag(tag):
@@ -23,6 +24,16 @@ def check_type_tag(tag):
         )
 
 
+def check_min_version(version):
+    if parse_version(version) > parse_version(C.VERSION):
+        raise cfgv.ValidationError(
+            'pre-commit version {} is required but version {} is installed.  '
+            'Perhaps run `pip install --upgrade pre-commit`.'.format(
+                version, C.VERSION,
+            ),
+        )
+
+
 def _make_argparser(filenames_help):
     parser = argparse.ArgumentParser()
     parser.add_argument('filenames', nargs='*', help=filenames_help)
@@ -231,6 +242,11 @@ CONFIG_SCHEMA = cfgv.Map(
     ),
     cfgv.Optional('exclude', cfgv.check_regex, '^$'),
     cfgv.Optional('fail_fast', cfgv.check_bool, False),
+    cfgv.Optional(
+        'minimum_pre_commit_version',
+        cfgv.check_and(cfgv.check_string, check_min_version),
+        '0',
+    ),
 )
 
 

`minimum_pre_commit_version` at the top level in configuration
Similar to the one that's currently allowed on individual hooks, allow this at the top level of the `.pre-commit-config.yaml`
diff --git a/tests/clientlib_test.py b/tests/clientlib_test.py
index 839bcaf..a79c5a0 100644
--- a/tests/clientlib_test.py
+++ b/tests/clientlib_test.py
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
 import cfgv
 import pytest
 
+import pre_commit.constants as C
 from pre_commit.clientlib import check_type_tag
 from pre_commit.clientlib import CONFIG_HOOK_DICT
 from pre_commit.clientlib import CONFIG_REPO_DICT
@@ -234,3 +235,23 @@ def test_meta_hook_invalid(config_repo):
 def test_default_language_version_invalid(mapping):
     with pytest.raises(cfgv.ValidationError):
         cfgv.validate(mapping, DEFAULT_LANGUAGE_VERSION)
+
+
+def test_minimum_pre_commit_version_failing():
+    with pytest.raises(cfgv.ValidationError) as excinfo:
+        cfg = {'repos': [], 'minimum_pre_commit_version': '999'}
+        cfgv.validate(cfg, CONFIG_SCHEMA)
+    assert str(excinfo.value) == (
+        '\n'
+        '==> At Config()\n'
+        '==> At key: minimum_pre_commit_version\n'
+        '=====> pre-commit version 999 is required but version {} is '
+        'installed.  Perhaps run `pip install --upgrade pre-commit`.'.format(
+            C.VERSION,
+        )
+    )
+
+
+def test_minimum_pre_commit_version_passing():
+    cfg = {'repos': [], 'minimum_pre_commit_version': '0'}
+    cfgv.validate(cfg, CONFIG_SCHEMA)

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio mock
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
aspy.yaml==1.3.0
cfgv==3.4.0
coverage==7.8.0
distlib==0.3.9
exceptiongroup==1.2.2
execnet==2.1.1
filelock==3.18.0
identify==2.6.9
importlib_metadata==8.6.1
iniconfig==2.1.0
mock==5.2.0
nodeenv==1.9.1
packaging==24.2
platformdirs==4.3.7
pluggy==1.5.0
-e git+https://github.com/pre-commit/pre-commit.git@264161c1824a4938366c588aa44688cd80f0e383#egg=pre_commit
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-cov==6.0.0
pytest-mock==3.14.0
pytest-xdist==3.6.1
PyYAML==6.0.2
six==1.17.0
toml==0.10.2
tomli==2.2.1
typing_extensions==4.13.0
virtualenv==20.29.3
zipp==3.21.0

name: pre-commit
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - aspy-yaml==1.3.0
      - cfgv==3.4.0
      - coverage==7.8.0
      - distlib==0.3.9
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - filelock==3.18.0
      - identify==2.6.9
      - importlib-metadata==8.6.1
      - iniconfig==2.1.0
      - mock==5.2.0
      - nodeenv==1.9.1
      - packaging==24.2
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-cov==6.0.0
      - pytest-mock==3.14.0
      - pytest-xdist==3.6.1
      - pyyaml==6.0.2
      - six==1.17.0
      - toml==0.10.2
      - tomli==2.2.1
      - typing-extensions==4.13.0
      - virtualenv==20.29.3
      - zipp==3.21.0
prefix: /opt/conda/envs/pre-commit

tests/clientlib_test.py::test_minimum_pre_commit_version_failing
tests/clientlib_test.py::test_check_type_tag_failures[definitely-not-a-tag] tests/clientlib_test.py::test_check_type_tag_failures[fiel] tests/clientlib_test.py::test_config_valid[config_obj0-True] tests/clientlib_test.py::test_config_valid[config_obj1-True] tests/clientlib_test.py::test_config_valid[config_obj2-False] tests/clientlib_test.py::test_local_hooks_with_rev_fails tests/clientlib_test.py::test_config_with_local_hooks_definition_passes tests/clientlib_test.py::test_config_schema_does_not_contain_defaults tests/clientlib_test.py::test_validate_manifest_main_ok tests/clientlib_test.py::test_validate_config_main_ok tests/clientlib_test.py::test_validate_config_old_list_format_ok tests/clientlib_test.py::test_mains_not_ok[validate_config_main] tests/clientlib_test.py::test_mains_not_ok[validate_manifest_main] tests/clientlib_test.py::test_valid_manifests[manifest_obj0-True] tests/clientlib_test.py::test_valid_manifests[manifest_obj1-True] tests/clientlib_test.py::test_valid_manifests[manifest_obj2-True] tests/clientlib_test.py::test_migrate_sha_to_rev_ok[dct0] tests/clientlib_test.py::test_migrate_sha_to_rev_ok[dct1] tests/clientlib_test.py::test_migrate_sha_to_rev_ok[dct2] tests/clientlib_test.py::test_migrate_sha_to_rev_ok[dct3] tests/clientlib_test.py::test_migrate_sha_to_rev_dont_specify_both tests/clientlib_test.py::test_migrate_sha_to_rev_conditional_check_failures[dct0] tests/clientlib_test.py::test_migrate_sha_to_rev_conditional_check_failures[dct1] tests/clientlib_test.py::test_migrate_sha_to_rev_conditional_check_failures[dct2] tests/clientlib_test.py::test_migrate_to_sha_apply_default tests/clientlib_test.py::test_migrate_to_sha_ok tests/clientlib_test.py::test_meta_hook_invalid[config_repo0] tests/clientlib_test.py::test_meta_hook_invalid[config_repo1] tests/clientlib_test.py::test_meta_hook_invalid[config_repo2] tests/clientlib_test.py::test_default_language_version_invalid[mapping0] tests/clientlib_test.py::test_default_language_version_invalid[mapping1] tests/clientlib_test.py::test_minimum_pre_commit_version_passing
pre_commit/clientlib.py
pre_commit/clientlib.py