diff -pruN 4.3.0-1/.github/workflows/languages.yaml 4.4.0-1/.github/workflows/languages.yaml
--- 4.3.0-1/.github/workflows/languages.yaml	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/.github/workflows/languages.yaml	2025-11-08 21:11:43.000000000 +0000
@@ -21,7 +21,7 @@ jobs:
         fetch-depth: 0
     - uses: actions/setup-python@v4
       with:
-        python-version: 3.9
+        python-version: '3.10'
     - name: install deps
       run: python -mpip install -e . -r requirements-dev.txt
     - name: vars
@@ -39,7 +39,7 @@ jobs:
     - uses: asottile/workflows/.github/actions/fast-checkout@v1.8.1
     - uses: actions/setup-python@v4
       with:
-        python-version: 3.9
+        python-version: '3.10'
 
     - run: echo "$CONDA\Scripts" >> "$GITHUB_PATH"
       shell: bash
diff -pruN 4.3.0-1/.github/workflows/main.yml 4.4.0-1/.github/workflows/main.yml
--- 4.3.0-1/.github/workflows/main.yml	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/.github/workflows/main.yml	2025-11-08 21:11:43.000000000 +0000
@@ -14,10 +14,10 @@ jobs:
   main-windows:
     uses: asottile/workflows/.github/workflows/tox.yml@v1.8.1
     with:
-      env: '["py39"]'
+      env: '["py310"]'
       os: windows-latest
   main-linux:
     uses: asottile/workflows/.github/workflows/tox.yml@v1.8.1
     with:
-      env: '["py39", "py310", "py311", "py312"]'
+      env: '["py310", "py311", "py312", "py313"]'
       os: ubuntu-latest
diff -pruN 4.3.0-1/.pre-commit-config.yaml 4.4.0-1/.pre-commit-config.yaml
--- 4.3.0-1/.pre-commit-config.yaml	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/.pre-commit-config.yaml	2025-11-08 21:11:43.000000000 +0000
@@ -1,6 +1,6 @@
 repos:
 -   repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v5.0.0
+    rev: v6.0.0
     hooks:
     -   id: trailing-whitespace
     -   id: end-of-file-fixer
@@ -10,24 +10,24 @@ repos:
     -   id: name-tests-test
     -   id: requirements-txt-fixer
 -   repo: https://github.com/asottile/setup-cfg-fmt
-    rev: v2.8.0
+    rev: v3.1.0
     hooks:
     -   id: setup-cfg-fmt
 -   repo: https://github.com/asottile/reorder-python-imports
-    rev: v3.15.0
+    rev: v3.16.0
     hooks:
     -   id: reorder-python-imports
-        exclude: ^(pre_commit/resources/|testing/resources/python3_hooks_repo/)
-        args: [--py39-plus, --add-import, 'from __future__ import annotations']
+        exclude: ^pre_commit/resources/
+        args: [--py310-plus, --add-import, 'from __future__ import annotations']
 -   repo: https://github.com/asottile/add-trailing-comma
-    rev: v3.2.0
+    rev: v4.0.0
     hooks:
     -   id: add-trailing-comma
 -   repo: https://github.com/asottile/pyupgrade
-    rev: v3.20.0
+    rev: v3.21.0
     hooks:
     -   id: pyupgrade
-        args: [--py39-plus]
+        args: [--py310-plus]
 -   repo: https://github.com/hhatto/autopep8
     rev: v2.3.2
     hooks:
@@ -37,7 +37,7 @@ repos:
     hooks:
     -   id: flake8
 -   repo: https://github.com/pre-commit/mirrors-mypy
-    rev: v1.17.1
+    rev: v1.18.2
     hooks:
     -   id: mypy
         additional_dependencies: [types-pyyaml]
diff -pruN 4.3.0-1/CHANGELOG.md 4.4.0-1/CHANGELOG.md
--- 4.3.0-1/CHANGELOG.md	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/CHANGELOG.md	2025-11-08 21:11:43.000000000 +0000
@@ -1,3 +1,27 @@
+4.4.0 - 2025-11-08
+==================
+
+### Features
+- Add `--fail-fast` option to `pre-commit run`.
+    - #3528 PR by @JulianMaurin.
+- Upgrade `ruby-build` / `rbenv`.
+    - #3566 PR by @asottile.
+    - #3565 issue by @MRigal.
+- Add `language: unsupported` / `language: unsupported_script` as aliases
+  for `language: system` / `language: script` (which will eventually be
+  deprecated).
+    - #3577 PR by @asottile.
+- Add support docker-in-docker detection for cgroups v2.
+    - #3535 PR by @br-rhrbacek.
+    - #3360 issue by @JasonAlt.
+
+### Fixes
+- Handle when docker gives `SecurityOptions: null`.
+    - #3537 PR by @asottile.
+    - #3514 issue by @jenstroeger.
+- Fix error context for invalid `stages` in `.pre-commit-config.yaml`.
+    - #3576 PR by @asottile.
+
 4.3.0 - 2025-08-09
 ==================
 
@@ -71,7 +95,7 @@
     - #3315 PR by @asottile.
     - #2732 issue by @asottile.
 
-### Migrating
+### Updating
 - `language: python_venv` has been removed -- use `language: python` instead.
     - #3320 PR by @asottile.
     - #2734 issue by @asottile.
@@ -159,7 +183,7 @@
 - Use `time.monotonic()` for more accurate hook timing.
     - #3024 PR by @adamchainz.
 
-### Migrating
+### Updating
 - Require npm 6.x+ for `language: node` hooks.
     - #2996 PR by @RoelAdriaans.
     - #1983 issue by @henryiii.
diff -pruN 4.3.0-1/debian/changelog 4.4.0-1/debian/changelog
--- 4.3.0-1/debian/changelog	2025-08-11 04:34:10.000000000 +0000
+++ 4.4.0-1/debian/changelog	2025-11-12 06:01:31.000000000 +0000
@@ -1,3 +1,11 @@
+pre-commit (4.4.0-1) sid; urgency=medium
+
+  * Removing rules-requires-root, not needed anymore.
+  * Merging upstream version 4.4.0.
+  * Updating watch file to version 5.
+
+ -- Daniel Baumann <daniel@debian.org>  Wed, 12 Nov 2025 07:01:31 +0100
+
 pre-commit (4.3.0-1) sid; urgency=medium
 
   * Merging upstream version 4.3.0.
diff -pruN 4.3.0-1/debian/control 4.4.0-1/debian/control
--- 4.3.0-1/debian/control	2025-08-11 04:33:59.000000000 +0000
+++ 4.4.0-1/debian/control	2025-11-12 06:00:55.000000000 +0000
@@ -7,7 +7,6 @@ Build-Depends:
  dh-sequence-python3,
  python3-all,
  python3-setuptools,
-Rules-Requires-Root: no
 Standards-Version: 4.7.2
 Homepage: https://github.com/pre-commit/pre-commit
 Vcs-Browser: https://forgejo.debian.net/pre-commit/pre-commit
diff -pruN 4.3.0-1/debian/watch 4.4.0-1/debian/watch
--- 4.3.0-1/debian/watch	2025-08-11 04:33:42.000000000 +0000
+++ 4.4.0-1/debian/watch	2025-11-12 06:01:25.000000000 +0000
@@ -1,2 +1,5 @@
-version=4
-https://github.com/pre-commit/pre-commit/tags .*/v?(\d.*)@ARCHIVE_EXT@
+Version: 5
+
+Template: Github
+Owner: pre-commit
+Project: @PACKAGE@
diff -pruN 4.3.0-1/pre_commit/all_languages.py 4.4.0-1/pre_commit/all_languages.py
--- 4.3.0-1/pre_commit/all_languages.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/all_languages.py	2025-11-08 21:11:43.000000000 +0000
@@ -19,9 +19,9 @@ from pre_commit.languages import python
 from pre_commit.languages import r
 from pre_commit.languages import ruby
 from pre_commit.languages import rust
-from pre_commit.languages import script
 from pre_commit.languages import swift
-from pre_commit.languages import system
+from pre_commit.languages import unsupported
+from pre_commit.languages import unsupported_script
 
 
 languages: dict[str, Language] = {
@@ -43,8 +43,8 @@ languages: dict[str, Language] = {
     'r': r,
     'ruby': ruby,
     'rust': rust,
-    'script': script,
     'swift': swift,
-    'system': system,
+    'unsupported': unsupported,
+    'unsupported_script': unsupported_script,
 }
 language_names = sorted(languages)
diff -pruN 4.3.0-1/pre_commit/clientlib.py 4.4.0-1/pre_commit/clientlib.py
--- 4.3.0-1/pre_commit/clientlib.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/clientlib.py	2025-11-08 21:11:43.000000000 +0000
@@ -6,6 +6,7 @@ import os.path
 import re
 import shlex
 import sys
+from collections.abc import Callable
 from collections.abc import Sequence
 from typing import Any
 from typing import NamedTuple
@@ -116,11 +117,12 @@ class StagesMigrationNoDefault(NamedTupl
         if self.key not in dct:
             return
 
-        val = dct[self.key]
-        cfgv.check_array(cfgv.check_any)(val)
+        with cfgv.validate_context(f'At key: {self.key}'):
+            val = dct[self.key]
+            cfgv.check_array(cfgv.check_any)(val)
 
-        val = [transform_stage(v) for v in val]
-        cfgv.check_array(cfgv.check_one_of(STAGES))(val)
+            val = [transform_stage(v) for v in val]
+            cfgv.check_array(cfgv.check_one_of(STAGES))(val)
 
     def apply_default(self, dct: dict[str, Any]) -> None:
         if self.key not in dct:
@@ -189,6 +191,42 @@ class DeprecatedDefaultStagesWarning(Nam
         raise NotImplementedError
 
 
+def _translate_language(name: str) -> str:
+    return {
+        'system': 'unsupported',
+        'script': 'unsupported_script',
+    }.get(name, name)
+
+
+class LanguageMigration(NamedTuple):  # remove
+    key: str
+    check_fn: Callable[[object], None]
+
+    def check(self, dct: dict[str, Any]) -> None:
+        if self.key not in dct:
+            return
+
+        with cfgv.validate_context(f'At key: {self.key}'):
+            self.check_fn(_translate_language(dct[self.key]))
+
+    def apply_default(self, dct: dict[str, Any]) -> None:
+        if self.key not in dct:
+            return
+
+        dct[self.key] = _translate_language(dct[self.key])
+
+    def remove_default(self, dct: dict[str, Any]) -> None:
+        raise NotImplementedError
+
+
+class LanguageMigrationRequired(LanguageMigration):  # replace with Required
+    def check(self, dct: dict[str, Any]) -> None:
+        if self.key not in dct:
+            raise cfgv.ValidationError(f'Missing required key: {self.key}')
+
+        super().check(dct)
+
+
 MANIFEST_HOOK_DICT = cfgv.Map(
     'Hook', 'id',
 
@@ -202,7 +240,7 @@ MANIFEST_HOOK_DICT = cfgv.Map(
     cfgv.Required('id', cfgv.check_string),
     cfgv.Required('name', cfgv.check_string),
     cfgv.Required('entry', cfgv.check_string),
-    cfgv.Required('language', cfgv.check_one_of(language_names)),
+    LanguageMigrationRequired('language', cfgv.check_one_of(language_names)),
     cfgv.Optional('alias', cfgv.check_string, ''),
 
     cfgv.Optional('files', check_string_regex, ''),
@@ -367,8 +405,10 @@ META_HOOK_DICT = cfgv.Map(
     'Hook', 'id',
     cfgv.Required('id', cfgv.check_string),
     cfgv.Required('id', cfgv.check_one_of(tuple(k for k, _ in _meta))),
-    # language must be system
-    cfgv.Optional('language', cfgv.check_one_of({'system'}), 'system'),
+    # language must be `unsupported`
+    cfgv.Optional(
+        'language', cfgv.check_one_of({'unsupported'}), 'unsupported',
+    ),
     # entry cannot be overridden
     NotAllowed('entry', cfgv.check_any),
     *(
@@ -401,8 +441,10 @@ CONFIG_HOOK_DICT = cfgv.Map(
         for item in MANIFEST_HOOK_DICT.items
         if item.key != 'id'
         if item.key != 'stages'
+        if item.key != 'language'  # remove
     ),
     StagesMigrationNoDefault('stages', []),
+    LanguageMigration('language', cfgv.check_one_of(language_names)),  # remove
     *_COMMON_HOOK_WARNINGS,
 )
 LOCAL_HOOK_DICT = cfgv.Map(
diff -pruN 4.3.0-1/pre_commit/commands/hook_impl.py 4.4.0-1/pre_commit/commands/hook_impl.py
--- 4.3.0-1/pre_commit/commands/hook_impl.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/commands/hook_impl.py	2025-11-08 21:11:43.000000000 +0000
@@ -106,6 +106,7 @@ def _ns(
         hook=None,
         verbose=False,
         show_diff_on_failure=False,
+        fail_fast=False,
     )
 
 
diff -pruN 4.3.0-1/pre_commit/commands/migrate_config.py 4.4.0-1/pre_commit/commands/migrate_config.py
--- 4.3.0-1/pre_commit/commands/migrate_config.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/commands/migrate_config.py	2025-11-08 21:11:43.000000000 +0000
@@ -3,7 +3,7 @@ from __future__ import annotations
 import functools
 import itertools
 import textwrap
-from typing import Callable
+from collections.abc import Callable
 
 import cfgv
 import yaml
diff -pruN 4.3.0-1/pre_commit/commands/run.py 4.4.0-1/pre_commit/commands/run.py
--- 4.3.0-1/pre_commit/commands/run.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/commands/run.py	2025-11-08 21:11:43.000000000 +0000
@@ -298,7 +298,8 @@ def _run_hooks(
             verbose=args.verbose, use_color=args.color,
         )
         retval |= current_retval
-        if current_retval and (config['fail_fast'] or hook.fail_fast):
+        fail_fast = (config['fail_fast'] or hook.fail_fast or args.fail_fast)
+        if current_retval and fail_fast:
             break
     if retval and args.show_diff_on_failure and prior_diff:
         if args.all_files:
diff -pruN 4.3.0-1/pre_commit/file_lock.py 4.4.0-1/pre_commit/file_lock.py
--- 4.3.0-1/pre_commit/file_lock.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/file_lock.py	2025-11-08 21:11:43.000000000 +0000
@@ -3,8 +3,8 @@ from __future__ import annotations
 import contextlib
 import errno
 import sys
+from collections.abc import Callable
 from collections.abc import Generator
-from typing import Callable
 
 
 if sys.platform == 'win32':  # pragma: no cover (windows)
diff -pruN 4.3.0-1/pre_commit/git.py 4.4.0-1/pre_commit/git.py
--- 4.3.0-1/pre_commit/git.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/git.py	2025-11-08 21:11:43.000000000 +0000
@@ -219,7 +219,7 @@ def check_for_cygwin_mismatch() -> None:
 
         if is_cygwin_python ^ is_cygwin_git:
             exe_type = {True: '(cygwin)', False: '(windows)'}
-            logger.warn(
+            logger.warning(
                 f'pre-commit has detected a mix of cygwin python / git\n'
                 f'This combination is not supported, it is likely you will '
                 f'receive an error later in the program.\n'
diff -pruN 4.3.0-1/pre_commit/languages/docker.py 4.4.0-1/pre_commit/languages/docker.py
--- 4.3.0-1/pre_commit/languages/docker.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/languages/docker.py	2025-11-08 21:11:43.000000000 +0000
@@ -1,9 +1,11 @@
 from __future__ import annotations
 
+import contextlib
 import functools
 import hashlib
 import json
 import os
+import re
 from collections.abc import Sequence
 
 from pre_commit import lang_base
@@ -17,31 +19,33 @@ get_default_version = lang_base.basic_ge
 health_check = lang_base.basic_health_check
 in_env = lang_base.no_env  # no special environment for docker
 
+_HOSTNAME_MOUNT_RE = re.compile(
+    rb"""
+    /containers
+    (?:/overlay-containers)?
+    /([a-z0-9]{64})
+    (?:/userdata)?
+    /hostname
+    """,
+    re.VERBOSE,
+)
+
+
+def _get_container_id() -> str | None:
+    with contextlib.suppress(FileNotFoundError):
+        with open('/proc/1/mountinfo', 'rb') as f:
+            for line in f:
+                m = _HOSTNAME_MOUNT_RE.search(line)
+                if m:
+                    return m[1].decode()
 
-def _is_in_docker() -> bool:
-    try:
-        with open('/proc/1/cgroup', 'rb') as f:
-            return b'docker' in f.read()
-    except FileNotFoundError:
-        return False
-
-
-def _get_container_id() -> str:
-    # It's assumed that we already check /proc/1/cgroup in _is_in_docker. The
-    # cpuset cgroup controller existed since cgroups were introduced so this
-    # way of getting the container ID is pretty reliable.
-    with open('/proc/1/cgroup', 'rb') as f:
-        for line in f.readlines():
-            if line.split(b':')[1] == b'cpuset':
-                return os.path.basename(line.split(b':')[2]).strip().decode()
-    raise RuntimeError('Failed to find the container ID in /proc/1/cgroup.')
+    return None
 
 
 def _get_docker_path(path: str) -> str:
-    if not _is_in_docker():
-        return path
-
     container_id = _get_container_id()
+    if container_id is None:
+        return path
 
     try:
         _, out, _ = cmd_output_b('docker', 'inspect', container_id)
@@ -115,7 +119,7 @@ def _is_rootless() -> bool:  # pragma: w
         return (
             # docker:
             # https://docs.docker.com/reference/api/engine/version/v1.48/#tag/System/operation/SystemInfo
-            'name=rootless' in info.get('SecurityOptions', ()) or
+            'name=rootless' in (info.get('SecurityOptions') or ()) or
             # podman:
             # https://docs.podman.io/en/latest/_static/api.html?version=v5.4#tag/system/operation/SystemInfoLibpod
             info['host']['security']['rootless']
diff -pruN 4.3.0-1/pre_commit/languages/golang.py 4.4.0-1/pre_commit/languages/golang.py
--- 4.3.0-1/pre_commit/languages/golang.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/languages/golang.py	2025-11-08 21:11:43.000000000 +0000
@@ -90,8 +90,7 @@ def _infer_go_version(version: str) -> s
     if version != C.DEFAULT:
         return version
     resp = urllib.request.urlopen('https://go.dev/dl/?mode=json')
-    # TODO: 3.9+ .removeprefix('go')
-    return json.load(resp)[0]['version'][2:]
+    return json.load(resp)[0]['version'].removeprefix('go')
 
 
 def _get_url(version: str) -> str:
diff -pruN 4.3.0-1/pre_commit/languages/script.py 4.4.0-1/pre_commit/languages/script.py
--- 4.3.0-1/pre_commit/languages/script.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/languages/script.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,32 +0,0 @@
-from __future__ import annotations
-
-from collections.abc import Sequence
-
-from pre_commit import lang_base
-from pre_commit.prefix import Prefix
-
-ENVIRONMENT_DIR = None
-get_default_version = lang_base.basic_get_default_version
-health_check = lang_base.basic_health_check
-install_environment = lang_base.no_install
-in_env = lang_base.no_env
-
-
-def run_hook(
-        prefix: Prefix,
-        entry: str,
-        args: Sequence[str],
-        file_args: Sequence[str],
-        *,
-        is_local: bool,
-        require_serial: bool,
-        color: bool,
-) -> tuple[int, bytes]:
-    cmd = lang_base.hook_cmd(entry, args)
-    cmd = (prefix.path(cmd[0]), *cmd[1:])
-    return lang_base.run_xargs(
-        cmd,
-        file_args,
-        require_serial=require_serial,
-        color=color,
-    )
diff -pruN 4.3.0-1/pre_commit/languages/system.py 4.4.0-1/pre_commit/languages/system.py
--- 4.3.0-1/pre_commit/languages/system.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/languages/system.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,10 +0,0 @@
-from __future__ import annotations
-
-from pre_commit import lang_base
-
-ENVIRONMENT_DIR = None
-get_default_version = lang_base.basic_get_default_version
-health_check = lang_base.basic_health_check
-install_environment = lang_base.no_install
-in_env = lang_base.no_env
-run_hook = lang_base.basic_run_hook
diff -pruN 4.3.0-1/pre_commit/languages/unsupported.py 4.4.0-1/pre_commit/languages/unsupported.py
--- 4.3.0-1/pre_commit/languages/unsupported.py	1970-01-01 00:00:00.000000000 +0000
+++ 4.4.0-1/pre_commit/languages/unsupported.py	2025-11-08 21:11:43.000000000 +0000
@@ -0,0 +1,10 @@
+from __future__ import annotations
+
+from pre_commit import lang_base
+
+ENVIRONMENT_DIR = None
+get_default_version = lang_base.basic_get_default_version
+health_check = lang_base.basic_health_check
+install_environment = lang_base.no_install
+in_env = lang_base.no_env
+run_hook = lang_base.basic_run_hook
diff -pruN 4.3.0-1/pre_commit/languages/unsupported_script.py 4.4.0-1/pre_commit/languages/unsupported_script.py
--- 4.3.0-1/pre_commit/languages/unsupported_script.py	1970-01-01 00:00:00.000000000 +0000
+++ 4.4.0-1/pre_commit/languages/unsupported_script.py	2025-11-08 21:11:43.000000000 +0000
@@ -0,0 +1,32 @@
+from __future__ import annotations
+
+from collections.abc import Sequence
+
+from pre_commit import lang_base
+from pre_commit.prefix import Prefix
+
+ENVIRONMENT_DIR = None
+get_default_version = lang_base.basic_get_default_version
+health_check = lang_base.basic_health_check
+install_environment = lang_base.no_install
+in_env = lang_base.no_env
+
+
+def run_hook(
+        prefix: Prefix,
+        entry: str,
+        args: Sequence[str],
+        file_args: Sequence[str],
+        *,
+        is_local: bool,
+        require_serial: bool,
+        color: bool,
+) -> tuple[int, bytes]:
+    cmd = lang_base.hook_cmd(entry, args)
+    cmd = (prefix.path(cmd[0]), *cmd[1:])
+    return lang_base.run_xargs(
+        cmd,
+        file_args,
+        require_serial=require_serial,
+        color=color,
+    )
diff -pruN 4.3.0-1/pre_commit/main.py 4.4.0-1/pre_commit/main.py
--- 4.3.0-1/pre_commit/main.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/main.py	2025-11-08 21:11:43.000000000 +0000
@@ -62,10 +62,10 @@ def _add_hook_type_option(parser: argpar
 
 def _add_run_options(parser: argparse.ArgumentParser) -> None:
     parser.add_argument('hook', nargs='?', help='A single hook-id to run')
-    parser.add_argument('--verbose', '-v', action='store_true', default=False)
+    parser.add_argument('--verbose', '-v', action='store_true')
     mutex_group = parser.add_mutually_exclusive_group(required=False)
     mutex_group.add_argument(
-        '--all-files', '-a', action='store_true', default=False,
+        '--all-files', '-a', action='store_true',
         help='Run on all the files in the repo.',
     )
     mutex_group.add_argument(
@@ -77,6 +77,10 @@ def _add_run_options(parser: argparse.Ar
         help='When hooks fail, run `git diff` directly afterward.',
     )
     parser.add_argument(
+        '--fail-fast', action='store_true',
+        help='Stop after the first failing hook.',
+    )
+    parser.add_argument(
         '--hook-stage',
         choices=clientlib.STAGES,
         type=clientlib.transform_stage,
@@ -275,7 +279,7 @@ def main(argv: Sequence[str] | None = No
     )
     _add_hook_type_option(install_parser)
     install_parser.add_argument(
-        '--allow-missing-config', action='store_true', default=False,
+        '--allow-missing-config', action='store_true',
         help=(
             'Whether to allow a missing `pre-commit` configuration file '
             'or exit with a failure code.'
Binary files 4.3.0-1/pre_commit/resources/rbenv.tar.gz and 4.4.0-1/pre_commit/resources/rbenv.tar.gz differ
Binary files 4.3.0-1/pre_commit/resources/ruby-build.tar.gz and 4.4.0-1/pre_commit/resources/ruby-build.tar.gz differ
diff -pruN 4.3.0-1/pre_commit/store.py 4.4.0-1/pre_commit/store.py
--- 4.3.0-1/pre_commit/store.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/store.py	2025-11-08 21:11:43.000000000 +0000
@@ -5,9 +5,9 @@ import logging
 import os.path
 import sqlite3
 import tempfile
+from collections.abc import Callable
 from collections.abc import Generator
 from collections.abc import Sequence
-from typing import Callable
 
 import pre_commit.constants as C
 from pre_commit import clientlib
diff -pruN 4.3.0-1/pre_commit/util.py 4.4.0-1/pre_commit/util.py
--- 4.3.0-1/pre_commit/util.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/util.py	2025-11-08 21:11:43.000000000 +0000
@@ -8,10 +8,10 @@ import shutil
 import stat
 import subprocess
 import sys
+from collections.abc import Callable
 from collections.abc import Generator
 from types import TracebackType
 from typing import Any
-from typing import Callable
 
 from pre_commit import parse_shebang
 
diff -pruN 4.3.0-1/pre_commit/xargs.py 4.4.0-1/pre_commit/xargs.py
--- 4.3.0-1/pre_commit/xargs.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/pre_commit/xargs.py	2025-11-08 21:11:43.000000000 +0000
@@ -7,12 +7,12 @@ import multiprocessing
 import os
 import subprocess
 import sys
+from collections.abc import Callable
 from collections.abc import Generator
 from collections.abc import Iterable
 from collections.abc import MutableMapping
 from collections.abc import Sequence
 from typing import Any
-from typing import Callable
 from typing import TypeVar
 
 from pre_commit import parse_shebang
diff -pruN 4.3.0-1/setup.cfg 4.4.0-1/setup.cfg
--- 4.3.0-1/setup.cfg	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/setup.cfg	2025-11-08 21:11:43.000000000 +0000
@@ -1,6 +1,6 @@
 [metadata]
 name = pre_commit
-version = 4.3.0
+version = 4.4.0
 description = A framework for managing and maintaining multi-language pre-commit hooks.
 long_description = file: README.md
 long_description_content_type = text/markdown
@@ -23,7 +23,7 @@ install_requires =
     nodeenv>=0.11.1
     pyyaml>=5.1
     virtualenv>=20.10.0
-python_requires = >=3.9
+python_requires = >=3.10
 
 [options.packages.find]
 exclude =
@@ -52,6 +52,7 @@ check_untyped_defs = true
 disallow_any_generics = true
 disallow_incomplete_defs = true
 disallow_untyped_defs = true
+enable_error_code = deprecated
 warn_redundant_casts = true
 warn_unused_ignores = true
 
diff -pruN 4.3.0-1/testing/make-archives 4.4.0-1/testing/make-archives
--- 4.3.0-1/testing/make-archives	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/testing/make-archives	2025-11-08 21:11:43.000000000 +0000
@@ -16,8 +16,8 @@ from collections.abc import Sequence
 
 
 REPOS = (
-    ('rbenv', 'https://github.com/rbenv/rbenv', '38e1fbb'),
-    ('ruby-build', 'https://github.com/rbenv/ruby-build', 'ed384c8'),
+    ('rbenv', 'https://github.com/rbenv/rbenv', '10e96bfc'),
+    ('ruby-build', 'https://github.com/rbenv/ruby-build', '447468b1'),
     (
         'ruby-download',
         'https://github.com/garnieretienne/rvm-download',
diff -pruN 4.3.0-1/testing/resources/python3_hooks_repo/.pre-commit-hooks.yaml 4.4.0-1/testing/resources/python3_hooks_repo/.pre-commit-hooks.yaml
--- 4.3.0-1/testing/resources/python3_hooks_repo/.pre-commit-hooks.yaml	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/testing/resources/python3_hooks_repo/.pre-commit-hooks.yaml	1970-01-01 00:00:00.000000000 +0000
@@ -1,6 +0,0 @@
--   id: python3-hook
-    name: Python 3 Hook
-    entry: python3-hook
-    language: python
-    language_version: python3
-    files: \.py$
diff -pruN 4.3.0-1/testing/resources/python3_hooks_repo/py3_hook.py 4.4.0-1/testing/resources/python3_hooks_repo/py3_hook.py
--- 4.3.0-1/testing/resources/python3_hooks_repo/py3_hook.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/testing/resources/python3_hooks_repo/py3_hook.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,8 +0,0 @@
-import sys
-
-
-def main():
-    print(sys.version_info[0])
-    print(repr(sys.argv[1:]))
-    print('Hello World')
-    return 0
diff -pruN 4.3.0-1/testing/resources/python3_hooks_repo/setup.py 4.4.0-1/testing/resources/python3_hooks_repo/setup.py
--- 4.3.0-1/testing/resources/python3_hooks_repo/setup.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/testing/resources/python3_hooks_repo/setup.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,8 +0,0 @@
-from setuptools import setup
-
-setup(
-    name='python3_hook',
-    version='0.0.0',
-    py_modules=['py3_hook'],
-    entry_points={'console_scripts': ['python3-hook = py3_hook:main']},
-)
diff -pruN 4.3.0-1/testing/resources/system_hook_with_spaces_repo/.pre-commit-hooks.yaml 4.4.0-1/testing/resources/system_hook_with_spaces_repo/.pre-commit-hooks.yaml
--- 4.3.0-1/testing/resources/system_hook_with_spaces_repo/.pre-commit-hooks.yaml	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/testing/resources/system_hook_with_spaces_repo/.pre-commit-hooks.yaml	1970-01-01 00:00:00.000000000 +0000
@@ -1,5 +0,0 @@
--   id: system-hook-with-spaces
-    name: System hook with spaces
-    entry: bash -c 'echo "Hello World"'
-    language: system
-    files: \.sh$
diff -pruN 4.3.0-1/testing/util.py 4.4.0-1/testing/util.py
--- 4.3.0-1/testing/util.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/testing/util.py	2025-11-08 21:11:43.000000000 +0000
@@ -40,6 +40,7 @@ def run_opts(
         color=False,
         verbose=False,
         hook=None,
+        fail_fast=False,
         remote_branch='',
         local_branch='',
         from_ref='',
@@ -65,6 +66,7 @@ def run_opts(
         color=color,
         verbose=verbose,
         hook=hook,
+        fail_fast=fail_fast,
         remote_branch=remote_branch,
         local_branch=local_branch,
         from_ref=from_ref,
diff -pruN 4.3.0-1/tests/clientlib_test.py 4.4.0-1/tests/clientlib_test.py
--- 4.3.0-1/tests/clientlib_test.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/tests/clientlib_test.py	2025-11-08 21:11:43.000000000 +0000
@@ -309,6 +309,27 @@ def test_validate_optional_sensible_rege
     assert caplog.record_tuples == [('pre_commit', logging.WARNING, warning)]
 
 
+def test_invalid_stages_error():
+    cfg = {'repos': [sample_local_config()]}
+    cfg['repos'][0]['hooks'][0]['stages'] = ['invalid']
+
+    with pytest.raises(cfgv.ValidationError) as excinfo:
+        cfgv.validate(cfg, CONFIG_SCHEMA)
+
+    assert str(excinfo.value) == (
+        '\n'
+        '==> At Config()\n'
+        '==> At key: repos\n'
+        "==> At Repository(repo='local')\n"
+        '==> At key: hooks\n'
+        "==> At Hook(id='do_not_commit')\n"
+        # this line was missing due to the custom validator
+        '==> At key: stages\n'
+        '==> At index 0\n'
+        "=====> Expected one of commit-msg, manual, post-checkout, post-commit, post-merge, post-rewrite, pre-commit, pre-merge-commit, pre-push, pre-rebase, prepare-commit-msg but got: 'invalid'"  # noqa: E501
+    )
+
+
 def test_warning_for_deprecated_stages(caplog):
     config_obj = sample_local_config()
     config_obj['hooks'][0]['stages'] = ['commit', 'push']
@@ -359,6 +380,26 @@ def test_no_warning_for_non_deprecated_d
     assert caplog.record_tuples == []
 
 
+def test_unsupported_language_migration():
+    cfg = {'repos': [sample_local_config(), sample_local_config()]}
+    cfg['repos'][0]['hooks'][0]['language'] = 'system'
+    cfg['repos'][1]['hooks'][0]['language'] = 'script'
+
+    cfgv.validate(cfg, CONFIG_SCHEMA)
+    ret = cfgv.apply_defaults(cfg, CONFIG_SCHEMA)
+
+    assert ret['repos'][0]['hooks'][0]['language'] == 'unsupported'
+    assert ret['repos'][1]['hooks'][0]['language'] == 'unsupported_script'
+
+
+def test_unsupported_language_migration_language_required():
+    cfg = {'repos': [sample_local_config()]}
+    del cfg['repos'][0]['hooks'][0]['language']
+
+    with pytest.raises(cfgv.ValidationError):
+        cfgv.validate(cfg, CONFIG_SCHEMA)
+
+
 @pytest.mark.parametrize(
     'manifest_obj',
     (
diff -pruN 4.3.0-1/tests/commands/run_test.py 4.4.0-1/tests/commands/run_test.py
--- 4.3.0-1/tests/commands/run_test.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/tests/commands/run_test.py	2025-11-08 21:11:43.000000000 +0000
@@ -1104,6 +1104,19 @@ def test_fail_fast_not_prev_failures(cap
     assert printed.count(b'run me!') == 1
 
 
+def test_fail_fast_run_arg(cap_out, store, repo_with_failing_hook):
+    with modify_config() as config:
+        # More than one hook to demonstrate early exit
+        config['repos'][0]['hooks'] *= 2
+    stage_a_file()
+
+    ret, printed = _do_run(
+        cap_out, store, repo_with_failing_hook, run_opts(fail_fast=True),
+    )
+    # it should have only run one hook due to the CLI flag
+    assert printed.count(b'Failing hook') == 1
+
+
 def test_classifier_removes_dne():
     classifier = Classifier(('this_file_does_not_exist',))
     assert classifier.filenames == []
diff -pruN 4.3.0-1/tests/languages/docker_test.py 4.4.0-1/tests/languages/docker_test.py
--- 4.3.0-1/tests/languages/docker_test.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/tests/languages/docker_test.py	2025-11-08 21:11:43.000000000 +0000
@@ -14,40 +14,173 @@ from pre_commit.util import CalledProces
 from testing.language_helpers import run_language
 from testing.util import xfailif_windows
 
-DOCKER_CGROUP_EXAMPLE = b'''\
-12:hugetlb:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-11:blkio:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-10:freezer:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-9:cpu,cpuacct:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-8:pids:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-7:rdma:/
-6:net_cls,net_prio:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-5:cpuset:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-4:devices:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-3:memory:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-2:perf_event:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-1:name=systemd:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
-0::/system.slice/containerd.service
+DOCKER_CGROUPS_V1_MOUNTINFO_EXAMPLE = b'''\
+759 717 0:52 / / rw,relatime master:300 - overlay overlay rw,lowerdir=/var/lib/docker/overlay2/l/PCPE5P5IVGM7CFCPJR353N3ONK:/var/lib/docker/overlay2/l/EQFSDHFAJ333VEMEJD4ZTRIZCB,upperdir=/var/lib/docker/overlay2/0d9f6bf186030d796505b87d6daa92297355e47641e283d3c09d83a7f221e462/diff,workdir=/var/lib/docker/overlay2/0d9f6bf186030d796505b87d6daa92297355e47641e283d3c09d83a7f221e462/work
+760 759 0:58 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
+761 759 0:59 / /dev rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
+762 761 0:60 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666
+763 759 0:61 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs ro
+764 763 0:62 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,mode=755,inode64
+765 764 0:29 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/systemd ro,nosuid,nodev,noexec,relatime master:11 - cgroup cgroup rw,xattr,name=systemd
+766 764 0:32 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/rdma ro,nosuid,nodev,noexec,relatime master:15 - cgroup cgroup rw,rdma
+767 764 0:33 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/cpu,cpuacct ro,nosuid,nodev,noexec,relatime master:16 - cgroup cgroup rw,cpu,cpuacct
+768 764 0:34 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/cpuset ro,nosuid,nodev,noexec,relatime master:17 - cgroup cgroup rw,cpuset
+769 764 0:35 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/pids ro,nosuid,nodev,noexec,relatime master:18 - cgroup cgroup rw,pids
+770 764 0:36 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/memory ro,nosuid,nodev,noexec,relatime master:19 - cgroup cgroup rw,memory
+771 764 0:37 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/perf_event ro,nosuid,nodev,noexec,relatime master:20 - cgroup cgroup rw,perf_event
+772 764 0:38 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/net_cls,net_prio ro,nosuid,nodev,noexec,relatime master:21 - cgroup cgroup rw,net_cls,net_prio
+773 764 0:39 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/blkio ro,nosuid,nodev,noexec,relatime master:22 - cgroup cgroup rw,blkio
+774 764 0:40 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/misc ro,nosuid,nodev,noexec,relatime master:23 - cgroup cgroup rw,misc
+775 764 0:41 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/hugetlb ro,nosuid,nodev,noexec,relatime master:24 - cgroup cgroup rw,hugetlb
+776 764 0:42 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/devices ro,nosuid,nodev,noexec,relatime master:25 - cgroup cgroup rw,devices
+777 764 0:43 /docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7 /sys/fs/cgroup/freezer ro,nosuid,nodev,noexec,relatime master:26 - cgroup cgroup rw,freezer
+778 761 0:57 / /dev/mqueue rw,nosuid,nodev,noexec,relatime - mqueue mqueue rw
+779 761 0:63 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=65536k,inode64
+780 759 8:5 /var/lib/docker/containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/resolv.conf /etc/resolv.conf rw,relatime - ext4 /dev/sda5 rw,errors=remount-ro
+781 759 8:5 /var/lib/docker/containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/hostname /etc/hostname rw,relatime - ext4 /dev/sda5 rw,errors=remount-ro
+782 759 8:5 /var/lib/docker/containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/hosts /etc/hosts rw,relatime - ext4 /dev/sda5 rw,errors=remount-ro
+718 761 0:60 /0 /dev/console rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666
+719 760 0:58 /bus /proc/bus ro,nosuid,nodev,noexec,relatime - proc proc rw
+720 760 0:58 /fs /proc/fs ro,nosuid,nodev,noexec,relatime - proc proc rw
+721 760 0:58 /irq /proc/irq ro,nosuid,nodev,noexec,relatime - proc proc rw
+722 760 0:58 /sys /proc/sys ro,nosuid,nodev,noexec,relatime - proc proc rw
+723 760 0:58 /sysrq-trigger /proc/sysrq-trigger ro,nosuid,nodev,noexec,relatime - proc proc rw
+724 760 0:64 / /proc/asound ro,relatime - tmpfs tmpfs ro,inode64
+725 760 0:65 / /proc/acpi ro,relatime - tmpfs tmpfs ro,inode64
+726 760 0:59 /null /proc/kcore rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
+727 760 0:59 /null /proc/keys rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
+728 760 0:59 /null /proc/timer_list rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
+729 760 0:66 / /proc/scsi ro,relatime - tmpfs tmpfs ro,inode64
+730 763 0:67 / /sys/firmware ro,relatime - tmpfs tmpfs ro,inode64
+731 763 0:68 / /sys/devices/virtual/powercap ro,relatime - tmpfs tmpfs ro,inode64
+'''  # noqa: E501
+
+DOCKER_CGROUPS_V2_MOUNTINFO_EXAMPLE = b'''\
+721 386 0:45 / / rw,relatime master:218 - overlay overlay rw,lowerdir=/var/lib/docker/overlay2/l/QHZ7OM7P4AQD3XLG274ZPWAJCV:/var/lib/docker/overlay2/l/5RFG6SZWVGOG2NKEYXJDQCQYX5,upperdir=/var/lib/docker/overlay2/e4ad859fc5d4791932b9b976052f01fb0063e01de3cef916e40ae2121f6a166e/diff,workdir=/var/lib/docker/overlay2/e4ad859fc5d4791932b9b976052f01fb0063e01de3cef916e40ae2121f6a166e/work,nouserxattr
+722 721 0:48 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
+723 721 0:50 / /dev rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
+724 723 0:51 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666
+725 721 0:52 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs ro
+726 725 0:26 / /sys/fs/cgroup ro,nosuid,nodev,noexec,relatime - cgroup2 cgroup rw,nsdelegate,memory_recursiveprot
+727 723 0:47 / /dev/mqueue rw,nosuid,nodev,noexec,relatime - mqueue mqueue rw
+728 723 0:53 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=65536k,inode64
+729 721 8:3 /var/lib/docker/containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/resolv.conf /etc/resolv.conf rw,relatime - ext4 /dev/sda3 rw,errors=remount-ro
+730 721 8:3 /var/lib/docker/containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/hostname /etc/hostname rw,relatime - ext4 /dev/sda3 rw,errors=remount-ro
+731 721 8:3 /var/lib/docker/containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/hosts /etc/hosts rw,relatime - ext4 /dev/sda3 rw,errors=remount-ro
+387 723 0:51 /0 /dev/console rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666
+388 722 0:48 /bus /proc/bus ro,nosuid,nodev,noexec,relatime - proc proc rw
+389 722 0:48 /fs /proc/fs ro,nosuid,nodev,noexec,relatime - proc proc rw
+525 722 0:48 /irq /proc/irq ro,nosuid,nodev,noexec,relatime - proc proc rw
+526 722 0:48 /sys /proc/sys ro,nosuid,nodev,noexec,relatime - proc proc rw
+571 722 0:48 /sysrq-trigger /proc/sysrq-trigger ro,nosuid,nodev,noexec,relatime - proc proc rw
+572 722 0:57 / /proc/asound ro,relatime - tmpfs tmpfs ro,inode64
+575 722 0:58 / /proc/acpi ro,relatime - tmpfs tmpfs ro,inode64
+576 722 0:50 /null /proc/kcore rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
+577 722 0:50 /null /proc/keys rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
+578 722 0:50 /null /proc/timer_list rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,inode64
+579 722 0:59 / /proc/scsi ro,relatime - tmpfs tmpfs ro,inode64
+580 725 0:60 / /sys/firmware ro,relatime - tmpfs tmpfs ro,inode64
+'''  # noqa: E501
+
+PODMAN_CGROUPS_V1_MOUNTINFO_EXAMPLE = b'''\
+1200 915 0:57 / / rw,relatime - overlay overlay rw,lowerdir=/home/asottile/.local/share/containers/storage/overlay/l/ZWAU3VY3ZHABQJRBUAFPBX7R5D,upperdir=/home/asottile/.local/share/containers/storage/overlay/72504ef163fda63838930450553b7306412ccad139a007626732b3dc43af5200/diff,workdir=/home/asottile/.local/share/containers/storage/overlay/72504ef163fda63838930450553b7306412ccad139a007626732b3dc43af5200/work,volatile,userxattr
+1204 1200 0:62 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
+1205 1200 0:63 / /dev rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,uid=1000,gid=1000,inode64
+1206 1200 0:64 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs rw
+1207 1205 0:65 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=100004,mode=620,ptmxmode=666
+1208 1205 0:61 / /dev/mqueue rw,nosuid,nodev,noexec,relatime - mqueue mqueue rw
+1209 1200 0:53 /containers/overlay-containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/userdata/.containerenv /run/.containerenv rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=814036k,mode=700,uid=1000,gid=1000,inode64
+1210 1200 0:53 /containers/overlay-containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/userdata/resolv.conf /etc/resolv.conf rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=814036k,mode=700,uid=1000,gid=1000,inode64
+1211 1200 0:53 /containers/overlay-containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/userdata/hosts /etc/hosts rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=814036k,mode=700,uid=1000,gid=1000,inode64
+1212 1205 0:56 / /dev/shm rw,relatime - tmpfs shm rw,size=64000k,uid=1000,gid=1000,inode64
+1213 1200 0:53 /containers/overlay-containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/userdata/hostname /etc/hostname rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=814036k,mode=700,uid=1000,gid=1000,inode64
+1214 1206 0:66 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs cgroup rw,size=1024k,uid=1000,gid=1000,inode64
+1215 1214 0:43 / /sys/fs/cgroup/freezer ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,freezer
+1216 1214 0:42 /user.slice /sys/fs/cgroup/devices ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,devices
+1217 1214 0:41 / /sys/fs/cgroup/hugetlb ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,hugetlb
+1218 1214 0:40 / /sys/fs/cgroup/misc ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,misc
+1219 1214 0:39 / /sys/fs/cgroup/blkio ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,blkio
+1220 1214 0:38 / /sys/fs/cgroup/net_cls,net_prio ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,net_cls,net_prio
+1221 1214 0:37 / /sys/fs/cgroup/perf_event ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,perf_event
+1222 1214 0:36 /user.slice/user-1000.slice/user@1000.service /sys/fs/cgroup/memory ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,memory
+1223 1214 0:35 /user.slice/user-1000.slice/user@1000.service /sys/fs/cgroup/pids ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,pids
+1224 1214 0:34 / /sys/fs/cgroup/cpuset ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpuset
+1225 1214 0:33 / /sys/fs/cgroup/cpu,cpuacct ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpu,cpuacct
+1226 1214 0:32 / /sys/fs/cgroup/rdma ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,rdma
+1227 1214 0:29 /user.slice/user-1000.slice/user@1000.service/apps.slice/apps-org.gnome.Terminal.slice/vte-spawn-0c50448e-b395-4d76-8b92-379f16e5066f.scope /sys/fs/cgroup/systemd ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,xattr,name=systemd
+1228 1205 0:5 /null /dev/null rw,nosuid,noexec,relatime - devtmpfs udev rw,size=4031656k,nr_inodes=1007914,mode=755,inode64
+1229 1205 0:5 /zero /dev/zero rw,nosuid,noexec,relatime - devtmpfs udev rw,size=4031656k,nr_inodes=1007914,mode=755,inode64
+1230 1205 0:5 /full /dev/full rw,nosuid,noexec,relatime - devtmpfs udev rw,size=4031656k,nr_inodes=1007914,mode=755,inode64
+1231 1205 0:5 /tty /dev/tty rw,nosuid,noexec,relatime - devtmpfs udev rw,size=4031656k,nr_inodes=1007914,mode=755,inode64
+1232 1205 0:5 /random /dev/random rw,nosuid,noexec,relatime - devtmpfs udev rw,size=4031656k,nr_inodes=1007914,mode=755,inode64
+1233 1205 0:5 /urandom /dev/urandom rw,nosuid,noexec,relatime - devtmpfs udev rw,size=4031656k,nr_inodes=1007914,mode=755,inode64
+1234 1204 0:67 / /proc/acpi ro,relatime - tmpfs tmpfs rw,size=0k,uid=1000,gid=1000,inode64
+1235 1204 0:5 /null /proc/kcore rw,nosuid,noexec,relatime - devtmpfs udev rw,size=4031656k,nr_inodes=1007914,mode=755,inode64
+1236 1204 0:5 /null /proc/keys rw,nosuid,noexec,relatime - devtmpfs udev rw,size=4031656k,nr_inodes=1007914,mode=755,inode64
+1237 1204 0:5 /null /proc/timer_list rw,nosuid,noexec,relatime - devtmpfs udev rw,size=4031656k,nr_inodes=1007914,mode=755,inode64
+1238 1204 0:68 / /proc/scsi ro,relatime - tmpfs tmpfs rw,size=0k,uid=1000,gid=1000,inode64
+1239 1206 0:69 / /sys/firmware ro,relatime - tmpfs tmpfs rw,size=0k,uid=1000,gid=1000,inode64
+1240 1206 0:70 / /sys/dev/block ro,relatime - tmpfs tmpfs rw,size=0k,uid=1000,gid=1000,inode64
+1241 1204 0:62 /asound /proc/asound ro,relatime - proc proc rw
+1242 1204 0:62 /bus /proc/bus ro,relatime - proc proc rw
+1243 1204 0:62 /fs /proc/fs ro,relatime - proc proc rw
+1244 1204 0:62 /irq /proc/irq ro,relatime - proc proc rw
+1245 1204 0:62 /sys /proc/sys ro,relatime - proc proc rw
+1256 1204 0:62 /sysrq-trigger /proc/sysrq-trigger ro,relatime - proc proc rw
+916 1205 0:65 /0 /dev/console rw,relatime - devpts devpts rw,gid=100004,mode=620,ptmxmode=666
+'''  # noqa: E501
+
+PODMAN_CGROUPS_V2_MOUNTINFO_EXAMPLE = b'''\
+685 690 0:63 /containers/overlay-containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/userdata/resolv.conf /etc/resolv.conf rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=1637624k,nr_inodes=409406,mode=700,uid=1000,gid=1000,inode64
+686 690 0:63 /containers/overlay-containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/userdata/hosts /etc/hosts rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=1637624k,nr_inodes=409406,mode=700,uid=1000,gid=1000,inode64
+687 692 0:50 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=64000k,uid=1000,gid=1000,inode64
+688 690 0:63 /containers/overlay-containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/userdata/.containerenv /run/.containerenv rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=1637624k,nr_inodes=409406,mode=700,uid=1000,gid=1000,inode64
+689 690 0:63 /containers/overlay-containers/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7/userdata/hostname /etc/hostname rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=1637624k,nr_inodes=409406,mode=700,uid=1000,gid=1000,inode64
+690 546 0:55 / / rw,relatime - overlay overlay rw,lowerdir=/home/asottile/.local/share/containers/storage/overlay/l/NPOHYOD3PI3YW6TQSGBOVOUSK6,upperdir=/home/asottile/.local/share/containers/storage/overlay/565c206fb79f876ffd5f069b8bd7a97fb5e47d5d07396b0c395a4ed6725d4a8e/diff,workdir=/home/asottile/.local/share/containers/storage/overlay/565c206fb79f876ffd5f069b8bd7a97fb5e47d5d07396b0c395a4ed6725d4a8e/work,redirect_dir=nofollow,uuid=on,volatile,userxattr
+691 690 0:59 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
+692 690 0:61 / /dev rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,uid=1000,gid=1000,inode64
+693 690 0:62 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs rw
+694 692 0:66 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=100004,mode=620,ptmxmode=666
+695 692 0:58 / /dev/mqueue rw,nosuid,nodev,noexec,relatime - mqueue mqueue rw
+696 693 0:28 / /sys/fs/cgroup ro,nosuid,nodev,noexec,relatime - cgroup2 cgroup2 rw,nsdelegate,memory_recursiveprot
+698 692 0:6 /null /dev/null rw,nosuid,noexec,relatime - devtmpfs udev rw,size=8147812k,nr_inodes=2036953,mode=755,inode64
+699 692 0:6 /zero /dev/zero rw,nosuid,noexec,relatime - devtmpfs udev rw,size=8147812k,nr_inodes=2036953,mode=755,inode64
+700 692 0:6 /full /dev/full rw,nosuid,noexec,relatime - devtmpfs udev rw,size=8147812k,nr_inodes=2036953,mode=755,inode64
+701 692 0:6 /tty /dev/tty rw,nosuid,noexec,relatime - devtmpfs udev rw,size=8147812k,nr_inodes=2036953,mode=755,inode64
+702 692 0:6 /random /dev/random rw,nosuid,noexec,relatime - devtmpfs udev rw,size=8147812k,nr_inodes=2036953,mode=755,inode64
+703 692 0:6 /urandom /dev/urandom rw,nosuid,noexec,relatime - devtmpfs udev rw,size=8147812k,nr_inodes=2036953,mode=755,inode64
+704 691 0:67 / /proc/acpi ro,relatime - tmpfs tmpfs rw,size=0k,uid=1000,gid=1000,inode64
+705 691 0:6 /null /proc/kcore ro,nosuid,relatime - devtmpfs udev rw,size=8147812k,nr_inodes=2036953,mode=755,inode64
+706 691 0:6 /null /proc/keys ro,nosuid,relatime - devtmpfs udev rw,size=8147812k,nr_inodes=2036953,mode=755,inode64
+707 691 0:6 /null /proc/latency_stats ro,nosuid,relatime - devtmpfs udev rw,size=8147812k,nr_inodes=2036953,mode=755,inode64
+708 691 0:6 /null /proc/timer_list ro,nosuid,relatime - devtmpfs udev rw,size=8147812k,nr_inodes=2036953,mode=755,inode64
+709 691 0:68 / /proc/scsi ro,relatime - tmpfs tmpfs rw,size=0k,uid=1000,gid=1000,inode64
+710 693 0:69 / /sys/firmware ro,relatime - tmpfs tmpfs rw,size=0k,uid=1000,gid=1000,inode64
+711 693 0:70 / /sys/dev/block ro,relatime - tmpfs tmpfs rw,size=0k,uid=1000,gid=1000,inode64
+712 693 0:71 / /sys/devices/virtual/powercap ro,relatime - tmpfs tmpfs rw,size=0k,uid=1000,gid=1000,inode64
+713 691 0:59 /asound /proc/asound ro,nosuid,nodev,noexec,relatime - proc proc rw
+714 691 0:59 /bus /proc/bus ro,nosuid,nodev,noexec,relatime - proc proc rw
+715 691 0:59 /fs /proc/fs ro,nosuid,nodev,noexec,relatime - proc proc rw
+716 691 0:59 /irq /proc/irq ro,nosuid,nodev,noexec,relatime - proc proc rw
+717 691 0:59 /sys /proc/sys ro,nosuid,nodev,noexec,relatime - proc proc rw
+718 691 0:59 /sysrq-trigger /proc/sysrq-trigger ro,nosuid,nodev,noexec,relatime - proc proc rw
+547 692 0:66 /0 /dev/console rw,relatime - devpts devpts rw,gid=100004,mode=620,ptmxmode=666
 '''  # noqa: E501
 
 # The ID should match the above cgroup example.
 CONTAINER_ID = 'c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7'  # noqa: E501
 
-NON_DOCKER_CGROUP_EXAMPLE = b'''\
-12:perf_event:/
-11:hugetlb:/
-10:devices:/
-9:blkio:/
-8:rdma:/
-7:cpuset:/
-6:cpu,cpuacct:/
-5:freezer:/
-4:memory:/
-3:pids:/
-2:net_cls,net_prio:/
-1:name=systemd:/init.scope
-0::/init.scope
-'''
+NON_DOCKER_MOUNTINFO_EXAMPLE = b'''\
+21 27 0:19 / /sys rw,nosuid,nodev,noexec,relatime shared:7 - sysfs sysfs rw
+22 27 0:20 / /proc rw,nosuid,nodev,noexec,relatime shared:14 - proc proc rw
+23 27 0:5 / /dev rw,nosuid,relatime shared:2 - devtmpfs udev rw,size=10219484k,nr_inodes=2554871,mode=755,inode64
+24 23 0:21 / /dev/pts rw,nosuid,noexec,relatime shared:3 - devpts devpts rw,gid=5,mode=620,ptmxmode=000
+25 27 0:22 / /run rw,nosuid,nodev,noexec,relatime shared:5 - tmpfs tmpfs rw,size=2047768k,mode=755,inode64
+27 1 8:2 / / rw,relatime shared:1 - ext4 /dev/sda2 rw,errors=remount-ro
+28 21 0:6 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime shared:8 - securityfs securityfs rw
+29 23 0:24 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw,inode64
+30 25 0:25 / /run/lock rw,nosuid,nodev,noexec,relatime shared:6 - tmpfs tmpfs rw,size=5120k,inode64
+'''  # noqa: E501
 
 
 def test_docker_fallback_user():
@@ -89,7 +222,8 @@ def test_docker_user_rootless(info_ret):
     (
         (0, b'{"SecurityOptions": ["name=cgroupns"]}', b''),
         (0, b'{"host": {"security": {"rootless": false}}}', b''),
-        (0, b'{"respone_from_some_other_container_engine": true}', b''),
+        (0, b'{"response_from_some_other_container_engine": true}', b''),
+        (0, b'{"SecurityOptions": null}', b''),
         (1, b'', b''),
     ),
 )
@@ -98,9 +232,9 @@ def test_docker_user_non_rootless(info_r
         assert docker.get_docker_user() != ()
 
 
-def test_in_docker_no_file():
+def test_container_id_no_file():
     with mock.patch.object(builtins, 'open', side_effect=FileNotFoundError):
-        assert docker._is_in_docker() is False
+        assert docker._get_container_id() is None
 
 
 def _mock_open(data):
@@ -112,38 +246,33 @@ def _mock_open(data):
     )
 
 
-def test_in_docker_docker_in_file():
-    with _mock_open(DOCKER_CGROUP_EXAMPLE):
-        assert docker._is_in_docker() is True
-
-
-def test_in_docker_docker_not_in_file():
-    with _mock_open(NON_DOCKER_CGROUP_EXAMPLE):
-        assert docker._is_in_docker() is False
+def test_container_id_not_in_file():
+    with _mock_open(NON_DOCKER_MOUNTINFO_EXAMPLE):
+        assert docker._get_container_id() is None
 
 
 def test_get_container_id():
-    with _mock_open(DOCKER_CGROUP_EXAMPLE):
+    with _mock_open(DOCKER_CGROUPS_V1_MOUNTINFO_EXAMPLE):
+        assert docker._get_container_id() == CONTAINER_ID
+    with _mock_open(DOCKER_CGROUPS_V2_MOUNTINFO_EXAMPLE):
+        assert docker._get_container_id() == CONTAINER_ID
+    with _mock_open(PODMAN_CGROUPS_V1_MOUNTINFO_EXAMPLE):
+        assert docker._get_container_id() == CONTAINER_ID
+    with _mock_open(PODMAN_CGROUPS_V2_MOUNTINFO_EXAMPLE):
         assert docker._get_container_id() == CONTAINER_ID
-
-
-def test_get_container_id_failure():
-    with _mock_open(b''), pytest.raises(RuntimeError):
-        docker._get_container_id()
 
 
 def test_get_docker_path_not_in_docker_returns_same():
-    with mock.patch.object(docker, '_is_in_docker', return_value=False):
+    with _mock_open(b''):
         assert docker._get_docker_path('abc') == 'abc'
 
 
 @pytest.fixture
 def in_docker():
-    with mock.patch.object(docker, '_is_in_docker', return_value=True):
-        with mock.patch.object(
-            docker, '_get_container_id', return_value=CONTAINER_ID,
-        ):
-            yield
+    with mock.patch.object(
+        docker, '_get_container_id', return_value=CONTAINER_ID,
+    ):
+        yield
 
 
 def _linux_commonpath():
diff -pruN 4.3.0-1/tests/languages/script_test.py 4.4.0-1/tests/languages/script_test.py
--- 4.3.0-1/tests/languages/script_test.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/tests/languages/script_test.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,14 +0,0 @@
-from __future__ import annotations
-
-from pre_commit.languages import script
-from pre_commit.util import make_executable
-from testing.language_helpers import run_language
-
-
-def test_script_language(tmp_path):
-    exe = tmp_path.joinpath('main')
-    exe.write_text('#!/usr/bin/env bash\necho hello hello world\n')
-    make_executable(exe)
-
-    expected = (0, b'hello hello world\n')
-    assert run_language(tmp_path, script, 'main') == expected
diff -pruN 4.3.0-1/tests/languages/system_test.py 4.4.0-1/tests/languages/system_test.py
--- 4.3.0-1/tests/languages/system_test.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/tests/languages/system_test.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,9 +0,0 @@
-from __future__ import annotations
-
-from pre_commit.languages import system
-from testing.language_helpers import run_language
-
-
-def test_system_language(tmp_path):
-    expected = (0, b'hello hello world\n')
-    assert run_language(tmp_path, system, 'echo hello hello world') == expected
diff -pruN 4.3.0-1/tests/languages/unsupported_script_test.py 4.4.0-1/tests/languages/unsupported_script_test.py
--- 4.3.0-1/tests/languages/unsupported_script_test.py	1970-01-01 00:00:00.000000000 +0000
+++ 4.4.0-1/tests/languages/unsupported_script_test.py	2025-11-08 21:11:43.000000000 +0000
@@ -0,0 +1,14 @@
+from __future__ import annotations
+
+from pre_commit.languages import unsupported_script
+from pre_commit.util import make_executable
+from testing.language_helpers import run_language
+
+
+def test_unsupported_script_language(tmp_path):
+    exe = tmp_path.joinpath('main')
+    exe.write_text('#!/usr/bin/env bash\necho hello hello world\n')
+    make_executable(exe)
+
+    expected = (0, b'hello hello world\n')
+    assert run_language(tmp_path, unsupported_script, 'main') == expected
diff -pruN 4.3.0-1/tests/languages/unsupported_test.py 4.4.0-1/tests/languages/unsupported_test.py
--- 4.3.0-1/tests/languages/unsupported_test.py	1970-01-01 00:00:00.000000000 +0000
+++ 4.4.0-1/tests/languages/unsupported_test.py	2025-11-08 21:11:43.000000000 +0000
@@ -0,0 +1,10 @@
+from __future__ import annotations
+
+from pre_commit.languages import unsupported
+from testing.language_helpers import run_language
+
+
+def test_unsupported_language(tmp_path):
+    expected = (0, b'hello hello world\n')
+    ret = run_language(tmp_path, unsupported, 'echo hello hello world')
+    assert ret == expected
diff -pruN 4.3.0-1/tests/repository_test.py 4.4.0-1/tests/repository_test.py
--- 4.3.0-1/tests/repository_test.py	2025-08-09 18:54:49.000000000 +0000
+++ 4.4.0-1/tests/repository_test.py	2025-11-08 21:11:43.000000000 +0000
@@ -17,7 +17,7 @@ from pre_commit.clientlib import CONFIG_
 from pre_commit.clientlib import load_manifest
 from pre_commit.hook import Hook
 from pre_commit.languages import python
-from pre_commit.languages import system
+from pre_commit.languages import unsupported
 from pre_commit.prefix import Prefix
 from pre_commit.repository import _hook_installed
 from pre_commit.repository import all_hooks
@@ -80,13 +80,6 @@ def _test_hook_repo(
     assert out == expected
 
 
-def test_system_hook_with_spaces(tempdir_factory, store):
-    _test_hook_repo(
-        tempdir_factory, store, 'system_hook_with_spaces_repo',
-        'system-hook-with-spaces', [os.devnull], b'Hello World\n',
-    )
-
-
 def test_missing_executable(tempdir_factory, store):
     _test_hook_repo(
         tempdir_factory, store, 'not_found_exe',
@@ -431,7 +424,7 @@ def test_manifest_hooks(tempdir_factory,
         exclude_types=[],
         files='',
         id='bash_hook',
-        language='script',
+        language='unsupported_script',
         language_version='default',
         log_file='',
         minimum_pre_commit_version='0',
@@ -464,7 +457,7 @@ def test_non_installable_hook_error_for_
         'hooks': [{
             'id': 'system-hook',
             'name': 'system-hook',
-            'language': 'system',
+            'language': 'unsupported',
             'entry': 'python3 -c "import sys; print(sys.version)"',
             'language_version': 'python3.10',
         }],
@@ -476,7 +469,7 @@ def test_non_installable_hook_error_for_
     msg, = caplog.messages
     assert msg == (
         'The hook `system-hook` specifies `language_version` but is using '
-        'language `system` which does not install an environment.  '
+        'language `unsupported` which does not install an environment.  '
         'Perhaps you meant to use a specific language?'
     )
 
@@ -487,7 +480,7 @@ def test_non_installable_hook_error_for_
         'hooks': [{
             'id': 'system-hook',
             'name': 'system-hook',
-            'language': 'system',
+            'language': 'unsupported',
             'entry': 'python3 -c "import sys; print(sys.version)"',
             'additional_dependencies': ['astpretty'],
         }],
@@ -499,14 +492,14 @@ def test_non_installable_hook_error_for_
     msg, = caplog.messages
     assert msg == (
         'The hook `system-hook` specifies `additional_dependencies` but is '
-        'using language `system` which does not install an environment.  '
+        'using language `unsupported` which does not install an environment.  '
         'Perhaps you meant to use a specific language?'
     )
 
 
 def test_args_with_spaces_and_quotes(tmp_path):
     ret = run_language(
-        tmp_path, system,
+        tmp_path, unsupported,
         f"{shlex.quote(sys.executable)} -c 'import sys; print(sys.argv[1:])'",
         ('i have spaces', 'and"\'quotes', '$and !this'),
     )
