I don't know a function for doing this, does anyone know of one?
26 Answers
I found this example quite helpful:
https://github.com/visionmedia/express/blob/master/examples/error-pages/index.js
So, it is actually this part:
// "app.router" positions our routes
// above the middleware defined below,
// this means that Express will attempt
// to match & call routes _before_ continuing
// on, at which point we assume it's a 404 because
// no route has handled the request.
app.use(app.router);
// Since this is the last non-error-handling
// middleware use()d, we assume 404, as nothing else
// responded.
// $ curl http://localhost:3000/notfound
// $ curl http://localhost:3000/notfound -H "Accept: application/json"
// $ curl http://localhost:3000/notfound -H "Accept: text/plain"
app.use(function(req, res, next) {
res.status(404);
// respond with html page
if (req.accepts('html')) {
res.render('404', { url: req.url });
return;
}
// respond with json
if (req.accepts('json')) {
res.json({ error: 'Not found' });
return;
}
// default to plain-text. send()
res.type('txt').send('Not found');
});
-
Please define "handled"? What exactly marks the route as handled? – Timo Huovinen Nov 21 '13 at 20:19
-
2I supposed that no matching route was found until that point. – Felix Apr 29 '14 at 08:35
-
5FYI, use of `app.router` is now deprecated. See https://github.com/strongloop/express/wiki/Migrating-from-3.x-to-4.x#approuter – jacobq Nov 15 '14 at 16:18
-
4For the JSON response it may be better to use `res.json` instead of `res.send()`. They'd behave the same in your code but using `res.json` will do some magic in auto-converting objects to strings where `.send()` won't. Better safe than sorry. http://expressjs.com/api.html#res.json – wgp Dec 12 '14 at 18:54
-
14Now this question appears in the FAQ http://expressjs.com/starter/faq.html#how-do-you-handle-404s- – Ivan Fraixedes Jan 09 '15 at 16:02
-
You have to take care of OPTIONS requests when you have CORS, so maybe it should give 404 only when req.method == 'GET' || req.method == 'POST' – Max Feb 07 '20 at 14:21
-
as jacobq mentioned, the use of app.router is deprecated. Now you just need to remove the `app.router` line and add rest of the code after all other `app.get`, `app.post` requests. ```app.get('/' ...); app.post(...); // more middleware (executes after routes) app.use(function(req, res, next) {}); // error handling middleware app.use(function(err, req, res, next) {}); ``` – Suraj Ingle Jan 21 '22 at 22:47
I think you should first define all your routes and as the last route add
//The 404 Route (ALWAYS Keep this as the last route)
app.get('*', function(req, res){
res.status(404).send('what???');
});
An example app which does work:
app.js:
var express = require('express'),
app = express.createServer();
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.send('hello world');
});
//The 404 Route (ALWAYS Keep this as the last route)
app.get('*', function(req, res){
res.send('what???', 404);
});
app.listen(3000, '127.0.0.1');
alfred@alfred-laptop:~/node/stackoverflow/6528876$ mkdir public
alfred@alfred-laptop:~/node/stackoverflow/6528876$ find .
alfred@alfred-laptop:~/node/stackoverflow/6528876$ echo "I don't find a function for that... Anyone knows?" > public/README.txt
alfred@alfred-laptop:~/node/stackoverflow/6528876$ cat public/README.txt
.
./app.js
./public
./public/README.txt
alfred@alfred-laptop:~/node/stackoverflow/6528876$ curl http://localhost:3000/
hello world
alfred@alfred-laptop:~/node/stackoverflow/6528876$ curl http://localhost:3000/README.txt
I don't find a function for that... Anyone knows?
-
7Well... the problem is that the "*" matchs the .js and .css files already, and they're not specified in the app... well, i don't know if there are some way to catch exactly the same thing that the 404 error, or a way to overwrite the "Cannot get..." message. Anyway, thanks you – Jun 30 '11 at 03:16
-
2Are you using static middleware, because then you can still serve static files? – Alfred Jun 30 '11 at 03:27
-
4`app.get('/public/*', function(req, res){ res.sendfile(__dirname + '/public/' + req.url); })` you can use this route to send static files. it works fine with above "*" route. `app.use(express.static(__dirname + '/public'));` does not work for me, wired. – Chris Jul 15 '11 at 04:18
-
@Chris `//The 404 Route (ALWAYS Keep this as the last route) app.get('*', function(req, res){ res.send('what???', 404); });` I updated my answer to better reflect this. And gave a full example which does work. – Alfred Jul 15 '11 at 11:04
-
25This wasn't working for me, but then I discovered that my `app.use(express.static(...))` came after `app.use(app.router)`. Once I switched them it all came out fine. – Stephen Nov 04 '11 at 18:23
-
if Alfreds solution doesn't work for you check if in you app.configure block ...static comes before app.router: app.configure(function(){ app.use(express.static(__dirname + '/public')); @Alfred, maybe you could add that, many people run into that error. app.use(app.router); }); – ezmilhouse Nov 08 '11 at 23:22
-
But if I `POST` an invalid URL, it still says `Cannot POST...`. :( – Alba Mendez May 15 '12 at 12:41
-
5+1 for adding @Stephen's comment to your answer. This didn't work for me either until I put app.use(app.router) AFTER app.use(express.static(...)) – braitsch May 19 '12 at 00:34
-
1If anyone's trying to send a static file *with* a status of 404 [see here](http://expressjs.com/api.html#res.status). `res.status(404).sendfile('path/to/404.html');` – mnoble01 Jan 09 '14 at 20:38
-
1express deprecated res.send(body, status): Use res.status(status).send(body) instead – Hussein mahyoub Jun 13 '18 at 00:53
-
Best annswer, although FYI `express deprecated res.send(body, status): Use res.status(status).send(body) instead` as the answer is way old :P – Rishav Feb 01 '19 at 17:09
-
-
Better to use `app.use()` rather than `app.get()` so the 404 handler responds to all HTTP verbs (like POST, PUT, OPTIONS, etc...). – jfriend00 Sep 23 '22 at 03:29
You can put a middleware at the last position that throws a NotFound
error,
or even renders the 404 page directly:
app.use(function(req,res){
res.status(404).render('404.jade');
});

- 48,881
- 23
- 151
- 196

- 1,341
- 11
- 18
-
12Please consider a little more verbose answer next time... Examples are usually fine - and this is a good example - but some explanation can be very, very good as well... – Tonny Madsen Jul 03 '11 at 20:40
-
2+1 **Very good!** I think this is better than a last route, because that way you don't have to `use()` your `app.router` at the last time. (as in my case) – Alba Mendez May 13 '12 at 18:32
-
Besides, this replaces default behavior on **any** request (not only `GET`s). Try to `POST` a random URL with the other method; it will return the default `Cannot POST...`. An attacker would then know you're using Express.JS. – Alba Mendez May 13 '12 at 18:41
-
-
This should probably also have a status(404) res.status(404).render('404') – MartinWebb Mar 02 '17 at 19:18
The above answers are good, but in half of these you won't be getting 404 as your HTTP status code returned and in other half, you won't be able to have a custom template render. The best way to have a custom error page (404's) in Expressjs is
app.use(function(req, res, next){
res.status(404).render('404_error_template', {title: "Sorry, page not found"});
});
Place this code at the end of all your URL mappings.

- 8,980
- 5
- 43
- 48
-
@SushantGupta - What do you mean by 'valid existential URL mappings?' – Jonathan Bechtel Nov 18 '17 at 02:30
-
@JonathanBechtel As in have the above code block after your non erroneous URL routes. – Sushant Gupta Nov 19 '17 at 10:12
At the last line of app.js just put this function. This will override the default page-not-found error page:
app.use(function (req, res) {
res.status(404).render('error');
});
It will override all the requests that don't have a valid handler and render your own error page.

- 48,881
- 23
- 151
- 196

- 1,617
- 1
- 19
- 35
The answer to your question is:
app.use(function(req, res) {
res.status(404).end('error');
});
And there is a great article about why it is the best way here.

- 1,149
- 1
- 11
- 14
-
1
-
-
1I dont believe it. send() sets the header, sends data and finally ends the request, end() sends data without setting the header and ends the request. Source: https://stackoverflow.com/questions/29555290/what-is-the-difference-between-res-end-and-res-send. Last Reply of Patch92 – Jose Velasco Jul 13 '21 at 19:29
express-error-handler lets you specify custom templates, static pages, or error handlers for your errors. It also does other useful error-handling things that every app should implement, like protect against 4xx error DOS attacks, and graceful shutdown on unrecoverable errors. Here's how you do what you're asking for:
var errorHandler = require('express-error-handler'),
handler = errorHandler({
static: {
'404': 'path/to/static/404.html'
}
});
// After all your routes...
// Pass a 404 into next(err)
app.use( errorHandler.httpError(404) );
// Handle all unhandled errors:
app.use( handler );
Or for a custom handler:
handler = errorHandler({
handlers: {
'404': function err404() {
// do some custom thing here...
}
}
});
Or for a custom view:
handler = errorHandler({
views: {
'404': '404.jade'
}
});

- 4,711
- 1
- 25
- 33
There are some cases where 404 page cannot be written to be executed as the last route, especially if you have an asynchronous routing function that brings in a /route late to the party. The pattern below might be adopted in those cases.
var express = require("express.io"),
app = express(),
router = express.Router();
router.get("/hello", function (req, res) {
res.send("Hello World");
});
// Router is up here.
app.use(router);
app.use(function(req, res) {
res.send("Crime Scene 404. Do not repeat");
});
router.get("/late", function (req, res) {
res.send("Its OK to come late");
});
app.listen(8080, function (){
console.log("Ready");
});

- 241
- 2
- 4
-
2Brilliant, thank you! The only answer (?) that doesn't rely on the linear processing of express (i.e. "just put the error handler at the end"). – Nick Grealy Mar 27 '18 at 01:17
The above code didn't work for me.
So I found a new solution that actually works!
app.use(function(req, res, next) {
res.status(404).send('Unable to find the requested resource!');
});
Or you can even render it to a 404 page.
app.use(function(req, res, next) {
res.status(404).render("404page");
});
Hope this helped you!

- 3,599
- 12
- 30
- 49

- 33
- 4
https://github.com/robrighter/node-boilerplate/blob/master/templates/app/server.js
This is what node-boilerplate does.

- 142,938
- 30
- 279
- 274

- 19,396
- 17
- 44
- 54
// Add this middleware
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});

- 4,043
- 1
- 20
- 16
The easiest way to do it is to have a catch all for Error Page
// Step 1: calling express
const express = require("express");
const app = express();
Then
// require Path to get file locations
const path = require("path");
Now you can store all your "html" pages (including an error "html" page) in a variable
// Storing file locations in a variable
var indexPg = path.join(__dirname, "./htmlPages/index.html");
var aboutPg = path.join(__dirname, "./htmlPages/about.html");
var contactPg = path.join(__dirname, "./htmlPages/contact.html");
var errorPg = path.join(__dirname, "./htmlPages/404.html"); //this is your error page
Now you simply call the pages using the Get Method and have a catch all for any routes not available to direct to your error page using app.get("*")
//Step 2: Defining Routes
//default page will be your index.html
app.get("/", function(req,res){
res.sendFile(indexPg);
});
//about page
app.get("/about", function(req,res){
res.sendFile(aboutPg);
});
//contact page
app.get("/contact", function(req,res){
res.sendFile(contactPg);
});
//catch all endpoint will be Error Page
app.get("*", function(req,res){
res.sendFile(errorPg);
});
Don't forget to set up a Port and Listen for server:
// Setting port to listen on
const port = process.env.PORT || 8000;
// Listening on port
app.listen(port, function(){
console.log(`http://localhost:${port}`);
})
This should now show your error page for all unrecognized endpoints!

- 5,503
- 2
- 16
- 9
Hi please find the answer
const express = require('express');
const app = express();
const port = 8080;
app.get('/', (req, res) => res.send('Hello home!'));
app.get('/about-us', (req, res) => res.send('Hello about us!'));
app.post('/user/set-profile', (req, res) => res.send('Hello profile!'));
//last 404 page
app.get('*', (req, res) => res.send('Page Not found 404'));
app.listen(port, () => console.log(`Example app listening on port ${port}!`));

- 3,846
- 36
- 29
Covering of all HTTP verbs in express
In order to cover all HTTP verbs and all remaining paths you could use:
app.all('*', cb)
Final solution would look like so:
app.all('*', (req, res) =>{
res.status(404).json({
success: false,
data: '404'
})
})
You shouldn't forget to put the router in the end. Because order of routers matter.

- 181
- 2
- 2
In Express, 404 responses are not the result of an error, so the error-handler middleware will not capture them. All you need to do is add a middleware function at the very bottom of the stack (below all other functions) to handle a 404 response:
app.use(function (req, res, next) {
// YOU CAN CREATE A CUSTOM EJS FILE TO SHOW CUSTOM ERROR MESSAGE
res.status(404).render("404.ejs")
})

- 7,001
- 45
- 38
While the answers above are correct, for those who want to get this working in IISNODE you also need to specify
<configuration>
<system.webServer>
<httpErrors existingResponse="PassThrough"/>
</system.webServer>
<configuration>
in your web.config (otherwise IIS will eat your output).
-
2Thank you!!! You are the only on in the internet who seems to know that(or at least share that)! cheers – André Lucas Apr 16 '14 at 04:37
you can error handling according to content-type
Additionally, handling according to status code.
app.js
import express from 'express';
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// when status is 404, error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
if( 404 === err.status ){
res.format({
'text/plain': () => {
res.send({message: 'not found Data'});
},
'text/html': () => {
res.render('404.jade');
},
'application/json': () => {
res.send({message: 'not found Data'});
},
'default': () => {
res.status(406).send('Not Acceptable');
}
})
}
// when status is 500, error handler
if(500 === err.status) {
return res.send({message: 'error occur'});
}
});
404.jade
doctype html
html
head
title 404 Not Found
meta(http-equiv="Content-Type" content="text/html; charset=utf-8")
meta(name = "viewport" content="width=device-width, initial-scale=1.0 user-scalable=no")
body
h2 Not Found Page
h2 404 Error Code
If you can using res.format, You can write simple error handling code.
Recommendation res.format()
instead of res.accepts()
.
If the 500 error occurs in the previous code, if(500 == err.status){. . . }
is called

- 470
- 5
- 10
This method is easier, but it has to be the last thing after all your routes.
app.use( (req, res) => {
//render page not found
res.render('404')
})

- 45
- 6
If you use express-generator package:
next(err);
This code send you to the 404 middleware.

- 11
- 2
To send to a custom page:
app.get('*', function(req, res){
if (req.accepts('html')) {
res.send('404', '<script>location.href = "/the-404-page.html";</script>');
return;
}
});

- 2,071
- 23
- 15
I used the handler below to handle 404 error with a static .ejs
file.
Put this code in a route script and then require that file.js
through app.use()
in your app.js
/server.js
/www.js
(if using IntelliJ for NodeJS)
You can also use a static .html
file.
//Unknown route handler
router.get("[otherRoute]", function(request, response) {
response.status(404);
response.render("error404.[ejs]/[html]");
response.end();
});
This way, the running express server will response with a proper 404 error
and your website can also include a page that properly displays the server's 404 response properly. You can also include a navbar
in that 404 error template
that links to other important content of your website.

- 585
- 5
- 8
If you want to redirect to error pages from your functions (routes) then do following things -
Add general error messages code in your app.js -
app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message res.locals.error = req.app.get('env') === 'development' ? err : {} // render the error page // you can also serve different error pages // for example sake, I am just responding with simple error messages res.status(err.status || 500) if(err.status === 403){ return res.send('Action forbidden!'); } if(err.status === 404){ return res.send('Page not found!'); } // when status is 500, error handler if(err.status === 500) { return res.send('Server error occured!'); } res.render('error') })
In your function, instead of using a error-page redirect you can use set the error status first and then use next() for the code flow to go through above code -
if(FOUND){ ... }else{ // redirecting to general error page // any error code can be used (provided you have handled its error response) res.status(404) // calling next() will make the control to go call the step 1. error code // it will return the error response according to the error code given (provided you have handled its error response) next() }

- 1,644
- 20
- 21
The 404 page should be set up just before the call to app.listen.Express has support for * in route paths. This is a special character which matches anything. This can be used to create a route handler that matches all requests.
app.get('*', (req, res) => {
res.render('404', {
title: '404',
name: 'test',
errorMessage: 'Page not found.'
})
})

- 3,899
- 1
- 26
- 31

- 11
What I do after defining all routes is to catch potential 404 and forward to error handler, like this:
const httpError = require('http-errors');
...
// API router
app.use('/api/', routes);
// catch 404 and forward to error handler
app.use((req, res, next) => {
const err = new httpError(404)
return next(err);
});
module.exports = app;

- 2,948
- 2
- 22
- 41
First, create a route js file. Next, create a error.ejs file (if you are using ejs). Finally, add the following code in your route file
router.get('*', function(req, res){
res.render('error');
});

- 51
- 8
-
Think this has already been well covered. Why post this when there are better answers? – DᴀʀᴛʜVᴀᴅᴇʀ Sep 30 '21 at 22:17
app.get('*',function(req,res){
res.redirect('/login');
});

- 6,052
- 10
- 43
- 117

- 39
- 1