Skip to content

Unable to disable automatic SendEmailVerificationNotification listener registration in Laravel 11+ using new application bootstrapping API #57389

@clarkewing

Description

@clarkewing

Laravel Version

12.21.0

PHP Version

8.4.13

Description

Context

Laravel 11 introduced automatic registration of the SendEmailVerificationNotification listener for the Registered event.

The upgrade guide suggests disabling this behavior by defining an empty configureEmailVerification() method in an application's own EventServiceProvider.

However, with the new application bootstrapping API, this is no longer feasible in practice:

  • Application::configure() internally calls ApplicationBuilder::withEvents()
  • This forcibly registers the framework’s own Illuminate\Foundation\Support\Providers\EventServiceProvider, which in turn registers the SendEmailVerificationNotification listener before the application can override it
  • Overriding configureEmailVerification() in an application's own EventServiceProvider has no effect unless the developer manually reimplements the application bootstrap sequence and removes the withEvents() call

This has been brought up in #50783, #51187, and #52601, but I believe we're in a different situation here because of the issue with the new application bootstrapping API.

Workaround

To work around this, I had to bypass Application::configure() entirely and rebuild the boot sequence manually to prevent Laravel from registering the default event provider:

// bootstrap/app.php

  use App\Providers\AppServiceProvider;
  use Illuminate\Foundation\Application;
+ use Illuminate\Foundation\Configuration\ApplicationBuilder;
  use Illuminate\Foundation\Configuration\Exceptions;
  use Illuminate\Foundation\Configuration\Middleware;

- return Application::configure(basePath: dirname(__DIR__))
+ return new ApplicationBuilder(new Application(basePath: dirname(__DIR__)))
+     ->withKernels()
+     // Here we're intentionally removing the withEvents() call from Application::configure()
+     ->withCommands()
+     ->withProviders()
      ->withRouting(
          web: __DIR__.'/../routes/web.php',
          commands: __DIR__.'/../routes/console.php',
          health: '/up',
      )
      ->withMiddleware(function (Middleware $middleware) {
          //
      })
      ->withExceptions(function (Exceptions $exceptions) {
          //
      })->create();

This does work, but it feels like a hack and goes against the new application bootstrapping API's intention of providing a clean and fluent configuration layer.

Proposal:

There should be a supported way to disable this automatic listener registration using the new bootstrap API — possibly via something like ‑>withoutAuthEvents(), or a configurable method parameter?

Steps To Reproduce

  1. Install a fresh Laravel 11+ application using the new application bootstrapping API (bootstrap/app.php)

  2. Implement a User model that implements MustVerifyEmail

  3. Attempt to disable automatic email verification by defining an empty configureEmailVerification() method in your App\Providers\EventServiceProvider, as suggested in the upgrade guide:

public function configureEmailVerification(): void
{
    // Intentionally left blank
}
  1. Register a new user (/register)

  2. Expected: No VerifyEmail notification email is dispatched
    Actual: Laravel still dispatches a VerifyEmail notification email via the SendEmailVerificationNotification listener

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions