symfony/symfony · error · LogicException

To use form CSRF protection, "framework.csrf_protection" mus

Error message

To use form CSRF protection, "framework.csrf_protection" must be enabled.

What it means

Thrown during form configuration registration when form-level CSRF protection (form.csrf_protection.enabled) is turned on but the global CSRF protection (framework.csrf_protection) is not enabled, meaning the 'security.csrf.token_generator' container definition is absent. Symfony's form CSRF extension depends on the token generator service which is only registered when global CSRF protection is active. The check is at FrameworkExtension.php:828-830.

Source

Thrown at src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php:830

        return class_exists(Application::class);
    }

    private function registerFormConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader): void
    {
        $loader->load('form.php');

        if (!property_exists(ValidatorExtension::class, 'violationMapper')) {
            $container->removeDefinition('form.violation_mapper');
            $container->removeAlias(ViolationMapperInterface::class);
            $container->getDefinition('form.type_extension.form.validator')->replaceArgument(1, false);
        }
        if (null === $config['form']['csrf_protection']['enabled']) {
            $this->writeConfigEnabled('form.csrf_protection', $config['csrf_protection']['enabled'], $config['form']['csrf_protection']);
        }

        if ($this->readConfigEnabled('form.csrf_protection', $container, $config['form']['csrf_protection'])) {
            if (!$container->hasDefinition('security.csrf.token_generator')) {
                throw new \LogicException('To use form CSRF protection, "framework.csrf_protection" must be enabled.');
            }

            $loader->load('form_csrf.php');

            $container->setParameter('form.type_extension.csrf.enabled', true);
            $container->setParameter('form.type_extension.csrf.field_name', $config['form']['csrf_protection']['field_name']);
            $container->setParameter('form.type_extension.csrf.field_attr', $config['form']['csrf_protection']['field_attr']);
            $container->setParameter('.form.type_extension.csrf.token_id', $config['form']['csrf_protection']['token_id']);
        } else {
            $container->setParameter('form.type_extension.csrf.enabled', false);
        }

        if (!ContainerBuilder::willBeAvailable('symfony/translation', Translator::class, ['symfony/framework-bundle', 'symfony/form'])) {
            $container->removeDefinition('form.type_extension.upload.validator');
        }
    }

    private function registerHttpCacheConfiguration(array $config, ContainerBuilder $container, bool $httpMethodOverride, ?array $allowedHttpMethodOverride): void

View on GitHub (pinned to 698e28026c)

Solutions

  1. Enable global CSRF protection: set 'framework.csrf_protection.enabled: true' in config/packages/framework.yaml.
  2. Ensure symfony/security-csrf is installed: composer require symfony/security-csrf.
  3. If you intentionally don't want form CSRF, set 'framework.form.csrf_protection.enabled: false' to disable it explicitly.

Example fix

# before
framework:
    form:
        csrf_protection:
            enabled: true
    # csrf_protection not set → defaults to not enabled

# after
framework:
    csrf_protection:
        enabled: true
    form:
        csrf_protection:
            enabled: true
Defensive patterns

Strategy: validation

Validate before calling

// Validate config consistency before deploy
$csrfEnabled = $config['framework']['csrf_protection']['enabled'] ?? false;
$formCsrfEnabled = $config['framework']['form']['csrf_protection']['enabled'] ?? false;
if ($formCsrfEnabled && !$csrfEnabled) {
    throw new \LogicException('form.csrf_protection requires framework.csrf_protection to be enabled.');
}

Prevention

When it happens

Trigger: Configuring 'framework.form.csrf_protection.enabled: true' while 'framework.csrf_protection.enabled' is false or unset. The readConfigEnabled() call at line 828 returns true for form CSRF, but $container->hasDefinition('security.csrf.token_generator') at line 829 returns false.

Common situations: Developer enables form CSRF in a bundle config or via a config override without enabling the global CSRF protection. Or during a security audit hardening pass where form CSRF was turned on but the base CSRF service wasn't installed/enabled. Also common when symfony/security-csrf is not installed.

Related errors


AI-assisted analysis of symfony/symfony@698e28026c (2026-08-06). Data as JSON: /api/errors/fa8ca3f44d35bd4d. Report an issue: GitHub.