MERN deploy to heroku Cannot Get

My app works locally but on Heroku i get the following:

Here is my index.js:

const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const path = require('path');


mongoose.connect(process.env.URI || 'mongodb://localhost/book_trak', {
  useNewUrlParser: true,
  useUnifiedTopology: true
  .catch(err => console.log(err));

var db = mongoose.connection;
db.on('error', (err) => console.log(err));
db.once('open', () => console.log('we are connected'));

const app = express();

//body parser no longer needed 
app.use(express.urlencoded({ extended: false }))

app.use('/book', require('./routes/book'));
app.use('/author', require('./routes/author'));

if(process.env.NODE.ENV === 'production') {
  app.use(express.static(path.join(__dirname, 'front_end', 'build')));

  app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, 'front_end', 'build', 'index.html'))

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => console.log('running on Port ' + PORT)); 


  "name": "backend",
  "version": "1.0.0",
  "description": "",
  "engines": {
    "node": "12.16.0"
  "main": "index.js",
  "scripts": {
    "client-install": "cd front_end && npm install",
    "start": "node index",
    "server": "nodemon index",
    "client": "cd front_end && npm start",
    "dev": "concurrently \" npm run server  \" \" npm run client\"",
    "heroku-postbuild": "cd front_end && npm install && npm run build"
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "mongoose": "^5.9.7"
  "devDependencies": {
    "concurrently": "^5.1.0",
    "nodemon": "^2.0.2"

my files:


I’ve been searching in this forum and stackoverflow all day. I think the problem lies in connecting to the database but I am not sure.

Hello and welcome to the forum :partying_face:!

The first thing to try is check the Developer Tools console (F12 or Control + Shift + i opens it).

If no errors pop up on the console, then you should check (and/or share) the build logs (see below).

If there is nothing wrong (no errors/warnings), then start debugging your app by logging console messages on steps. For instance, put a console.log at the beginning of the server file, another one after the first route, etc.

To view the log files refer to the heroku documentation on logging.

Some things to note:

  • Your .env file may not be there, unless you’re committing it to your git repository (or any other way you’re deploying it). The usual way to create the .env is by using the heroku variables.
  • I think the problem might be on the static routes, but I’m not sure.
  • The port should be 80 (or the default).

Hope it helps :slight_smile:,


Thanks for taking the time to help me. I appreciate it.

I have one env variable which is my URI connection string. I saved it in the config vars in heroku. I also have the URI in the .env file but this file is listed in .gitignore.

this error comes up on the console:

As for the heroku logs:

2020-04-14T18:09:20.989565+00:00 app[web.1]: > backend@1.0.0 start /app
2020-04-14T18:09:20.989566+00:00 app[web.1]: > node index
2020-04-14T18:09:20.989566+00:00 app[web.1]:
2020-04-14T18:09:21.899885+00:00 app[web.1]: running on Port 18576
2020-04-14T18:09:22.451290+00:00 heroku[web.1]: State changed from starting to up       
2020-04-14T18:09:24.558048+00:00 heroku[router]: at=info method=GET path="/" request_id=eebab2d2-3ad8-4d3b-bc6c-5d68797f6fb9 fwd="" dyno=web.1 connect=0ms service=20ms status=404 bytes=415 protocol=https
2020-04-14T18:09:27.237052+00:00 heroku[router]: at=info method=GET path="/" request_id=e89bab28-ec44-4b44-91f2-6fd0e3a9ee2c fwd="" dyno=web.1 connect=1ms service=6ms status=404 bytes=415 protocol=https
2020-04-14T18:09:51.981924+00:00 app[web.1]: MongooseError [MongooseServerSelectionError]: connection <monitor> to closed
2020-04-14T18:09:51.981935+00:00 app[web.1]: at new MongooseServerSelectionError (/app/node_modules/mongoose/lib/error/serverSelection.js:22:11)
2020-04-14T18:09:51.981935+00:00 app[web.1]: at NativeConnection.Connection.openUri (/app/node_modules/mongoose/lib/connection.js:823:32)
2020-04-14T18:09:51.981936+00:00 app[web.1]: at Mongoose.connect (/app/node_modules/mongoose/lib/index.js:333:15)
2020-04-14T18:09:51.981937+00:00 app[web.1]: at Object.<anonymous> (/app/index.js:9:10) 
2020-04-14T18:09:51.981937+00:00 app[web.1]: at Module._compile (internal/modules/cjs/loader.js:1157:30)
2020-04-14T18:09:51.981938+00:00 app[web.1]: at Object.Module._extensions..js (internal/modules/cjs/loader.js:1177:10)
2020-04-14T18:09:51.981942+00:00 app[web.1]: at Module.load (internal/modules/cjs/loader.js:1001:32)
2020-04-14T18:09:51.981943+00:00 app[web.1]: at Function.Module._load (internal/modules/cjs/loader.js:900:14)
2020-04-14T18:09:51.981943+00:00 app[web.1]: at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
2020-04-14T18:09:51.981944+00:00 app[web.1]: at internal/main/run_main_module.js:18:47 {2020-04-14T18:09:51.981944+00:00 app[web.1]: message: 'connection <monitor> to closed',
2020-04-14T18:09:51.981944+00:00 app[web.1]: name: 'MongooseServerSelectionError',      
2020-04-14T18:09:51.981945+00:00 app[web.1]: reason: TopologyDescription {
2020-04-14T18:09:51.981945+00:00 app[web.1]: type: 'ReplicaSetNoPrimary',
2020-04-14T18:09:51.981946+00:00 app[web.1]: setName: null,
2020-04-14T18:09:51.981946+00:00 app[web.1]: maxSetVersion: null,
2020-04-14T18:09:51.981946+00:00 app[web.1]: maxElectionId: null,
2020-04-14T18:09:51.981947+00:00 app[web.1]: servers: Map {
2020-04-14T18:09:51.981947+00:00 app[web.1]: '' => [ServerDescription],
2020-04-14T18:09:51.981948+00:00 app[web.1]: '' => [ServerDescription],
2020-04-14T18:09:51.981948+00:00 app[web.1]: '' => [ServerDescription]
2020-04-14T18:09:51.981949+00:00 app[web.1]: },
2020-04-14T18:09:51.981949+00:00 app[web.1]: stale: false,
2020-04-14T18:09:51.981949+00:00 app[web.1]: compatible: true,
2020-04-14T18:09:51.981950+00:00 app[web.1]: compatibilityError: null,
2020-04-14T18:09:51.981950+00:00 app[web.1]: logicalSessionTimeoutMinutes: null,
2020-04-14T18:09:51.981950+00:00 app[web.1]: heartbeatFrequencyMS: 10000,
2020-04-14T18:09:51.981951+00:00 app[web.1]: localThresholdMS: 15,
2020-04-14T18:09:51.981951+00:00 app[web.1]: commonWireVersion: null
2020-04-14T18:09:51.981951+00:00 app[web.1]: },
2020-04-14T18:09:51.981952+00:00 app[web.1]: [Symbol(mongoErrorContextSymbol)]: {}
2020-04-14T18:09:51.981952+00:00 app[web.1]: }
2020-04-14T18:09:51.983681+00:00 app[web.1]: MongooseError [MongooseServerSelectionError]: connection <monitor> to closed

Sorry for the delay :sweat_smile:!

Hmm, there seems to be two problems:

  1. Your mongo connection seems to be wrong or it may be right, but heroku doesn’t have access to it. If you’re using, for instance, you would need to allow your app IP to pass through the firewall. If you’re using mlab, then I can’t help because I don’t have experience with it (but I suppose there is something similar to a firewall there).
  2. This may be due to the previous error, but your app doesn’t seem to find the root path. You will need to make sure the path to the client app (front_end) exists and was built. Check the heroku build logs for any errors.

Try fixing the first problem and see what happens.

I’ve never dealt with firewalls. Could you give me instructions on how to allow the app IP to pass through? Also, I am seeing suggestions that I should use in the network access settings of atlas. Is this a good idea?

It depends. It’s meant to be a production app? If so, then no, it’s a bad idea (for security–people could get access to your database and, possibly, your clients data-- and for performance–thousands of unauthorized people trying to access your database or having access to it is bad). Ideally, you should have a static IP (or range) pointing to your app which you would grant access to your database.

Now, if it’s a staging area (meant for tests) and there is no sensitive data (no passwords stored on plain text, no GPG keys, etc.), then it’s OK. Sometimes you have no alternatives either (read below).

First things first, you need to have the IP of your heroku app. If this is a free tier app, you may be forced to use, which grants access to everyone on the internet (without your username/password, it’s not too much of a problem, so use hard to guess username/password, ideally random).

If it’s not a free tier you should be able to get the IP from the dashboard.

For now, I’ll assume you’re using the free tier, hence we will allow public access (

  1. Login to your atlas.
  2. Make sure you’ve created the database you’re going to use, otherwise (on the left panel) click on Atlas -> Clusters -> Collections -> Create Database.
  3. On the left panel, click on Security -> Database Access -> Add new Database User. The idea is to create a new user with read/write access only to a specific database (in case your information leaks and the database is breached, your other databases and admin DB is protected).
    • Write the username and password.
    • Click on Add Default Privileges.
    • Where it says Select Role, choose readWrite
    • Where it says Database write the name of the database you want to use.
  4. Now, for the actual firewall, go to Security -> Network Access.
  5. Click on Add IP Address and fill the Whitelist Entry with and Confirm.

Give it a couple of minutes and you’re done. Just remember to delete this “public access” once your app is live (or if you upgrade your heroku app).

I went through the steps you listed. The page still says "Cannot Get / ". However, I am no longer seeing any errors on my heroku logs:

2020-04-14T21:02:16.944265+00:00 heroku[web.1]: State changed from starting to up  
2020-04-14T21:02:16.698939+00:00 app[web.1]: running on Port 29174
2020-04-14T21:02:17.400863+00:00 app[web.1]: we are connected
2020-04-14T21:02:17.794028+00:00 heroku[router]: at=info method=GET path="/" request_id=0de510c0-e046-4c74-8474-fc7fd7a570c1 fwd="" dyno=web.1 connect=1ms service=16ms status=404 bytes=415 protocol=https
2020-04-14T21:08:46.444836+00:00 heroku[router]: at=info method=GET path="/" request_id=f1a5e3df-288a-4172-8d9c-96159c088933 fwd="" dyno=web.1 connect=1ms service=10ms status=404 bytes=415 protocol=https
2020-04-14T21:13:14.119918+00:00 heroku[router]: at=info method=GET path="/" request_id=09409c91-8980-4b04-a3bc-784569a0439c fwd="" dyno=web.1 connect=1ms service=8ms status=404 bytes=415 protocol=https
2020-04-14T21:13:21.365478+00:00 heroku[router]: at=info method=GET path="/" request_id=8e5a1cc6-8a4d-4e40-8a94-f0fc4c9b98da fwd="" dyno=web.1 connect=2ms service=5ms status=404 bytes=415 protocol=https

I currently do not have a build file in my client (front_end). This was based on a tutorial I saw. The idea is that heroku will run the command to build. Could this be the problem?

Hey there! Heroku can be a pain… I’ve only dealt with the MEAN stack, but I reckon it shouldn’t be too farfetched to think that Heroku could be giving you the same problem it was giving me. It could be that Heroku cannot find your dist folder.

For example, my path looks like this… (Just look at my commits! LOL.)

I thought you could at least get this off your trial and error list if it’s not the problem! Hope it helps though. :slight_smile:

Thanks. But I have a feeling that the issue is in my heroku-postbuild script. I’ve seen that script written in so many ways. It confuses me.

I completely understand. I hope you get it solved! :smiley:

Problem SOLVED!!!

There was a typo:

if(process.env.NODE.ENV === 'production') {
  app.use(express.static(path.join(__dirname, 'front_end', 'build')));

  app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, 'front_end', 'build', 'index.html'))

should have been:

if(process.env.NODE_ENV === 'production') {

I used . instead of _

Thanks to all those who helped

1 Like