symfony/http-kernel · error · InvalidArgumentException

The controller for URI

Error message

The controller for URI "%s" is not callable: 

What it means

ControllerResolver::getController resolved the _controller attribute from the Request, but the resulting value is not callable. The message is appended with getControllerError() explaining why (e.g. class does not exist, method missing).

Solutions

  1. Fix the _controller value in the route definition to an existing, public, callable controller
  2. Check the appended detail from getControllerError() to see whether the class or the method is missing
  3. Clear the cache (cache:clear) so compiled route/controller data matches current code
  4. If using a service controller, ensure the service exists and use 'serviceId::method' or 'serviceId:methodName' syntax

Example fix

// before
#[Route('/foo', name: 'foo', '_controller' => 'App\\Controller\\FooControler::index')]
// after
#[Route('/foo', name: 'foo', '_controller' => 'App\\Controller\\FooController::index')]
Defensive patterns

Strategy: validation

Validate before calling

$ctrl = $request->attributes->get('_controller');
if (is_string($ctrl) && !is_callable($ctrl, true)) {
    [$class, $method] = array_pad(explode('::', $ctrl, 2), 2, '__invoke');
    if (!class_exists($class) || !method_exists($class, $method)) {
        throw new \InvalidArgumentException("Controller '$ctrl' is not callable");
    }
}

Type guard

function isStringCallableController(mixed $c): bool { return is_string($c) && is_callable($c, true); }

Try / catch

try { $controller = $resolver->getController($request); } catch (\InvalidArgumentException $e) {
    // 'The controller for URI ... is not callable'
}

Prevention

When it happens

Trigger: Request attributes contain a _controller value that resolves to a string or array that is_callable() rejects: a non-existent class::method, an instantiated object with an undefined method, or a malformed 'Class::method' string when the controller was found via the fallback path (not createController).

Common situations: Typo in _controller name in route annotations/attributes or YAML; controller method renamed or made private; controller string like 'App\\Controller\\Foo::bar' where class exists but ::bar does not; using a service method string without container support.

Related errors


AI-assisted analysis of symfony/http-kernel@aa3a39d728 (2026-09-13). Data as JSON: /api/errors/bf26e5bbf778b9b9. Report an issue: GitHub.

Appendix: source

Thrown at Controller/ControllerResolver.php:76

            return false;
        }

        if (\is_array($controller)) {
            if (isset($controller[0]) && \is_string($controller[0]) && isset($controller[1])) {
                try {
                    $controller[0] = $this->instantiateController($controller[0]);
                } catch (\Error|\LogicException $e) {
                    if (\is_callable($controller)) {
                        return $this->checkController($request, $controller);
                    }

                    throw $e;
                }
            }

            if (!\is_callable($controller)) {
                throw new \InvalidArgumentException(\sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($controller));
            }

            return $this->checkController($request, $controller);
        }

        if (\is_object($controller)) {
            if (!\is_callable($controller)) {
                throw new \InvalidArgumentException(\sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($controller));
            }

            return $this->checkController($request, $controller);
        }

        if (\function_exists($controller)) {
            return $this->checkController($request, $controller);
        }

        try {

View on GitHub (pinned to aa3a39d728)