How do you set a one-off access checker on a route? As far as we can tell, the "Simplified custom access checker" section of the handbook is outdated. The entirety of CheckProvider seems to be service oriented and this is the provider which has the $route-&gt;setOption('_access_checks', $checks); call. In turn, AccessManager::check has a $checks = $route-&gt;getOption('_access_checks') ?: array(); call. There's nothing which would accommodate one-off checkers like the handbook page suggests:

requirements:
  _custom_access: '\Drupal\example\Controller\ExampleController::access'


and based on our debugging, this is indeed not working. What is the current way, if any, to do this?
The handbook is correct. The access is handled by services. The normal way to implement a custom access check is to define a service in mymodule.services.yml. See this example from the core book module:

  access_check.book.removable:
    class: Drupal\book\Access\BookNodeIsRemovableAccessCheck
    arguments: ['@book.manager']
    tags:
      - { name: access_check, applies_to: _access_book_removable }


And then use this in routing:

_access_book_removable: 'TRUE'


Here you can choose your own arbitrary naming schema.

As described in the handbook, if you want to simplify this, you can reuse the service access_check.custom, which is already defined in core.services.yml:

  access_check.custom:
    class: Drupal\Core\Access\CustomAccessCheck
    arguments: ['@controller_resolver', '@access_arguments_resolver_factory']
    tags:
      - { name: access_check, applies_to: _custom_access }


Then you have to use _custom_access: for the route. You can not use something like _my_module_access: as before, the key must match the tag in the service definition.

The first solution puts the complete logic of the access check in a service and makes it reusable and self-explanatory. If you only need the access code in one route and want to place the access code in the controller class the second method provides a shortcut.