We are moving our forum in GitHub Discussions. For questions about Phalcon v3/v4 you can visit here and for Phalcon v5 here.

404 and notFoundAction


My notFoundAction() in ControllerBase never seems to be called.

I can do something like this; https://stackoverflow.com/questions/14071261/how-to-setup-a-404-page-in-phalcon but I thought notFoundAction() was "out-of-the-box". Didn't think I had to use ->forward(...) either.

What am I doing wrong? Thanks in advance.

(Regards from sunny Queensland, Australia)


Does the IndexController extends from your ControllerBase ?

Or you can set it in your router

$router = new Phalcon\Mvc\Router() $router->notFound(array( "controller" => "action" => whatever ))

Thanks for the reply - yes it does extend ControllerBase ?

I tried that snippet too - but no joy. If need be I'll post code; mainly just wondering why notFoundAction() is never called ("out-of-the-box" ) Still have

PhalconException: Action 'foo' was not found on handler 'index'


There is no such "notFoundAction" (out-of-the-box), implement that method on a controller could be insufficient, a not-found event is triggered when:

1) The passed URI to Phalcon\Mvc\Router does not match any of the routes set up on it 2) The router matches a URI but Phalcon\Mvc\Application can't load the module (if any) 3) The router matches a URI but Phalcon\Dispatcher can't find the controller file 4) The router matches a URI but Phalcon\Dispatcher can't find the controller class 5) The router matches a URI but Phalcon\Dispatcher can't find the action method in the controller class

Implement an action "notFound" would only work in the case 5.


Thanks for the explanation, so where is the correct place to register not-found event handler ? Dispatcher ?


Yes, most of the time intercepting these events in the dispatcher will allow to show a 404 to your users:

use Phalcon\Events\Manager as EventsManager,
    Phalcon\Dispatcher as Dispatcher;

$di['dispatcher'] = function() {

    $evManager = new EventsManager();

    $evManager->attach("dispatch:beforeException", function($event, $dispatcher, $exception) {
        switch ($exception->getCode()) {
            case Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
            case Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
                    'controller' => 'error',
                    'action'     => 'show404',
                return false;

    $dispatcher = new Dispatcher();
    return $dispatcher;


I implemented 404 errors as specified above, but the problem I am facing with is that the response is empty. Only the headers are sent. Can anyone help me?



How to make module not registered show 404 page?


I had the same problem and found the solution. The problem happens because the router is initialized with default routes (/:controller/:action and /:controller/:action/:params), so notFound is never called.

Solution1: clear routes before defining your own: $router->clear();

Solution 2: create the router without default routes: $router = new Phalcon\Mvc\Router(FALSE);