{"record":{"id":"41871ca77a3775a8","repo":"symfony/http-kernel","slug":"rate-limiter-s-does-not-exist-did-you-forget-to-configure-it","errorCode":null,"errorMessage":"Rate limiter \"%s\" does not exist. Did you forget to configure it? Available limiters: \"%s\".","messagePattern":"Rate limiter \"(.+?)\" does not exist\\. Did you forget to configure it\\? Available limiters: \"(.+?)\"\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"EventListener/RateLimitAttributeListener.php","lineNumber":57,"sourceCode":"    public function __construct(\n        private readonly ServiceProviderInterface $limiters,\n    ) {\n    }\n\n    /**\n     * @param ControllerAttributeEvent<RateLimit, ControllerArgumentsEvent> $event\n     */\n    public function onKernelControllerAttribute(ControllerAttributeEvent $event, ?string $eventName = null, ?EventDispatcherInterface $dispatcher = null): void\n    {\n        $request = $event->kernelEvent->getRequest();\n        $attribute = $event->attribute;\n\n        if ($attribute->methods && !\\in_array($request->getMethod(), $attribute->methods, true)) {\n            return;\n        }\n\n        if (!$this->limiters->has($attribute->limiter)) {\n            throw new \\InvalidArgumentException(\\sprintf('Rate limiter \"%s\" does not exist. Did you forget to configure it? Available limiters: \"%s\".', $attribute->limiter, implode('\", \"', array_keys($this->limiters->getProvidedServices()))));\n        }\n\n        if (null === $attribute->key) {\n            $key = ($request->getClientIp() ?? 'unknown').'~'.$request->getMethod().'~'.$request->getPathInfo();\n        } elseif (!\\is_string($key = $event->evaluate($attribute->key))) {\n            throw new \\TypeError(\\sprintf('The value of the \"$key\" option of the \"%s\" attribute must evaluate to a string, \"%s\" given.', RateLimit::class, get_debug_type($key)));\n        }\n\n        $rateLimit = $this->limiters->get($attribute->limiter)->create($key)->consume($attribute->tokens);\n\n        $candidate = $attribute->exposeHeaders && null !== $rateLimit->getResetAt()\n            ? new AppliedRateLimit($rateLimit, $attribute->tokens)\n            : null;\n\n        if (!$rateLimit->isAccepted()) {\n            $request->attributes->set(self::RATE_LIMIT_ATTRIBUTE, $candidate);\n\n            if ($dispatcher && class_exists(RateLimitExceededEvent::class)) {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/symfony/http-kernel/blob/aa3a39d7286a62cdfea98f0e69c651a3da6e36cf/EventListener/RateLimitAttributeListener.php#L39-L75","documentation":"RateLimitAttributeListener resolves the limiter named by the #[RateLimit] attribute from a container locator. If the named limiter service does not exist, an InvalidArgumentException is thrown listing the limiters that ARE configured.","triggerScenarios":"A controller annotated with #[RateLimit(limiter: 'foo')] where no limiter named 'foo' is registered (e.g. missing limiter config under framework.rate_limiter, or a typo in the limiter name), during onKernelControllerAttribute.","commonSituations":"Symfony config defining limiters under a different key than the attribute; forgetting symfony/rate-limiter configuration entirely; renaming a limiter without updating attributes; typo between YAML key and attribute value.","solutions":["Define the limiter in config: framework.rate_limiter.<name> with a factory policy matching the attribute's limiter value.","Correct the limiter name in #[RateLimit(limiter: ...)] to match an available limiter (see the exception's list).","Run config:dump-reference / debug:rate-limiter (if available) to verify registered limiter names."],"exampleFix":"// before\n#[RateLimit(limiter: 'api')]\n// after (with config: framework: rate_limiter: { basic: ... })\n#[RateLimit(limiter: 'basic')]","handlingStrategy":"validation","validationCode":"$available = array_keys($limiters->getProvidedServices());\nif (!in_array($limiterName, $available, true)) { throw new \\InvalidArgumentException(\"Unknown limiter '$limiterName'\"); }","typeGuard":null,"tryCatchPattern":"try { $listener->onKernelControllerAttribute($event, 'kernel.controller', ...); } catch (\\InvalidArgumentException $e) { /* surface misconfigured limiter name with the available list from the message */ }","preventionTips":["Keep #[RateLimit] limiter names in sync with framework.rate_limiter config keys","Add a config test that dumps registered limiters","Use a shared constant/class for limiter names instead of raw strings"],"tags":["rate-limiting","service-not-found","configuration","symfony"],"backgroundTag":"resource-not-found","analyzedSha":"aa3a39d7286a62cdfea98f0e69c651a3da6e36cf","analyzedAt":"2026-09-13T18:03:36.509Z","contentChangedAt":"2026-09-13T18:03:36.509Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}