Subscribing to Core Kernel Events in Drupalfor Drupal 11 , 10 , 9 , and 8

Last updated :  

So far in this tutorial you've seen how a module can define its own events. But most of the time, you don't need to invent anything — Drupal's core already fires a steady stream of events during every single request, and your module can simply raise its hand and say "let me know when that happens." Listening to a core kernel event is how you hook into the request/response lifecycle itself, before routing, after routing, on exceptions, and more — all without touching a single line of Drupal core.

What you'll learn in this lesson

  • What "kernel events" actually are, and where they fit in a request's lifecycle
  • How to register an event subscriber via a plain services.yml tag — no custom hook needed
  • How to read the event object HttpKernel hands you to inspect or alter the request/response
  • Why subscribing to a core event is often the right tool instead of a page-cache-unfriendly hook

Think of it like a security checkpoint with several stations

Picture an airport security line with multiple checkpoints: bag scan, ID check, boarding pass check, final gate check. Each checkpoint is a distinct moment in a traveler's journey, and an official stationed at any one of them can act — flag a bag, wave someone through, or reroute them — without needing to know what happens at the other stations. Drupal's HttpKernel works the same way: as a request travels from "just arrived" to "response sent," it passes through named checkpoints (KernelEvents::REQUEST, KernelEvents::RESPONSE, KernelEvents::EXCEPTION, and others), and any module can station a subscriber at one of them.

Registering a subscriber for a core event

services:
  my_module.request_subscriber:
    class: Drupal\my_module\EventSubscriber\RequestSubscriber
    tags:
      - { name: event_subscriber }

That event_subscriber tag is the entire registration step — Drupal's service container automatically collects every service tagged this way and asks it, via getSubscribedEvents(), which events it cares about. There's no hook to implement and nothing to enable manually; tagging the service is enough.

<?php

namespace Drupal\my_module\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class RequestSubscriber implements EventSubscriberInterface {

  public static function getSubscribedEvents(): array {
    return [
      KernelEvents::REQUEST => ['onRequest', 30],
    ];
  }

  public function onRequest(RequestEvent $event) {
    $request = $event->getRequest();
    if ($request->query->has('debug_mode')) {
      \Drupal::logger('my_module')->notice('Debug mode requested for @path', [
        '@path' => $request->getPathInfo(),
      ]);
    }
  }

}

getSubscribedEvents() returns an array keyed by event name, each mapping to a method name and an optional priority (higher runs first — the same priority convention you'll use for your own custom events in the next few lessons). The event object itself, RequestEvent, wraps the current request; different kernel events pass different event object types, each exposing whatever's relevant at that checkpoint (a response object for KernelEvents::RESPONSE, an exception for KernelEvents::EXCEPTION).

Why not just use a hook? Some core kernel events have no hook equivalent at all — KernelEvents::EXCEPTION, for instance, is how contributed modules build custom error pages, and there's no hook_exception() in Drupal. Where both exist, kernel events tend to run earlier and more predictably in the request lifecycle than hooks like hook_page_attachments(), which only fire once the page is actually being assembled.

Quick check: you want to redirect anonymous users away from a specific path before any page rendering even starts. Would KernelEvents::REQUEST or KernelEvents::RESPONSE be the right event to subscribe to? If you said REQUEST, you've got it — it fires at the very start of the lifecycle, before a controller has even run, which is exactly when a redirect needs to happen to avoid wasted work.

Key takeaways

  • Core kernel events (KernelEvents::REQUEST, ::RESPONSE, ::EXCEPTION, and others) let you hook into the HTTP request/response lifecycle at precise points, independent of Drupal's hook system.
  • Registering a subscriber is just a services.yml entry tagged event_subscriber — no hook implementation required.
  • getSubscribedEvents() maps event names to a method and optional priority; higher priority numbers run first.
  • Some kernel events (like exceptions) have no hook equivalent at all — subscribing is the only way to react to them.

Coming up next

Core events are useful, but the real power of Drupal's event system is defining your own events so other modules can react to things happening inside your module. Next, you'll create a custom event class of your own.