{"record":{"id":"b1b104958a137b4e","repo":"symfony/routing","slug":"the-routing-file-s-must-not-specify-both-the-firewall-key","errorCode":null,"errorMessage":"The routing file \"%s\" must not specify both the \"firewall\" key and the defaults key \"_firewall\" for \"%s\".","messagePattern":"The routing file \"(.+?)\" must not specify both the \"firewall\" key and the defaults key \"_firewall\" for \"(.+?)\"\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"Loader/ContentLoaderTrait.php","lineNumber":235,"sourceCode":"            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" contains unsupported keys for \"%s\": \"%s\". Expected one of: \"%s\".', $path, $name, implode('\", \"', $extraKeys), implode('\", \"', self::AVAILABLE_KEYS)));\n        }\n        if (isset($config['resource']) && isset($config['path'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify both the \"resource\" key and the \"path\" key for \"%s\". Choose between an import and a route definition.', $path, $name));\n        }\n        if (!isset($config['resource']) && isset($config['type'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The \"type\" key for the route definition \"%s\" in \"%s\" is unsupported. It is only available for imports in combination with the \"resource\" key.', $name, $path));\n        }\n        if (!isset($config['resource']) && !isset($config['path'])) {\n            throw new \\InvalidArgumentException(\\sprintf('You must define a \"path\" for the route \"%s\" in file \"%s\".', $name, $path));\n        }\n        if (isset($config['controller']) && isset($config['defaults']['_controller'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify both the \"controller\" key and the defaults key \"_controller\" for \"%s\".', $path, $name));\n        }\n        if (isset($config['stateless']) && isset($config['defaults']['_stateless'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify both the \"stateless\" key and the defaults key \"_stateless\" for \"%s\".', $path, $name));\n        }\n        if (isset($config['firewall']) && isset($config['defaults']['_firewall'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify both the \"firewall\" key and the defaults key \"_firewall\" for \"%s\".', $path, $name));\n        }\n    }\n\n    /**\n     * Validates that an alias definition only carries the `alias` and `deprecated` keys.\n     *\n     * @throws \\InvalidArgumentException If one of the provided config keys is not supported,\n     *                                   something is missing or the combination is nonsense\n     */\n    private function validateAlias(array $config, string $name, string $path): void\n    {\n        foreach ($config as $key => $value) {\n            if (!\\in_array($key, ['alias', 'deprecated'], true)) {\n                throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify other keys than \"alias\" and \"deprecated\" for \"%s\".', $path, $name));\n            }\n\n            if ('deprecated' === $key) {\n                if (!isset($value['package'])) {","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/symfony/routing/blob/83fa223250b50f4f018c011e101c330e65ac63cc/Loader/ContentLoaderTrait.php#L217-L253","documentation":"The firewall for a route may be set with the top-level 'firewall' key or via defaults['_firewall'], but specifying both is ambiguous and rejected. ContentLoaderTrait::validate() throws InvalidArgumentException when a route entry declares both.","triggerScenarios":"A route entry in a routing file containing both 'firewall: ...' and 'defaults: { _firewall: ... }'.","commonSituations":"Configs maintained across Symfony versions where the option moved between defaults and top level; team members adding the newer key without deleting the legacy one; copy-paste from mixed documentation.","solutions":["Remove defaults['_firewall'] and keep only the top-level 'firewall' key","Or delete the top-level 'firewall' key if the defaults form is required for your setup","Audit routing files for both spellings after framework upgrades"],"exampleFix":"# before\napp_secure:\n    path: /secure\n    firewall: main\n    defaults:\n        _firewall: main\n\n# after\napp_secure:\n    path: /secure\n    firewall: main","handlingStrategy":"validation","validationCode":"if (isset($config['firewall']) && isset($config['defaults']['_firewall'])) {\n    throw new \\LogicException('Use either \"firewall\" or defaults._firewall, not both.');\n}","typeGuard":"function hasSingleFirewall(array $config): bool { return !(isset($config['firewall']) && isset($config['defaults']['_firewall'])); }","tryCatchPattern":"try { $collection = $loader->load($file, 'yaml'); } catch (\\InvalidArgumentException $e) { /* duplicate firewall declaration; dedupe config */ }","preventionTips":["Use the top-level 'firewall' key only","Audit routing files for both spellings after upgrades","Keep routing config style consistent across the codebase"],"tags":["symfony","routing","config-validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"83fa223250b50f4f018c011e101c330e65ac63cc","analyzedAt":"2026-09-14T03:19:46.280Z","contentChangedAt":"2026-09-14T03:19:46.280Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}