express health check problem
debuck1718
HOBBYOP

3 months ago

This is the server.js file "const http = require("http");

const server = http.createServer(app);

let isShuttingDown = false;

const startApp = async () => {

try {

await connectMongo();

await startAgenda();

server.listen(PORT, "0.0.0.0", () => {

console.log Server running on port ${PORT} [${NODE_ENV}]);

});

} catch (err) {

console.error(" Fatal startup error:", err);

process.exit(1);

}

};

app.get("/", (req, res) => {

res.status(200).send("SmartStudentAct API is running ");

});

app.get(["/health", "/healthz"], (req, res) => {

res.status(200).json({

status: "ok",

uptime: process.uptime(),

timestamp: new Date().toISOString(),

});

});

const shutdown = async (signal) => {

if (isShuttingDown) return;

isShuttingDown = true;

console.log\n Received ${signal}, starting graceful shutdown...);

try {

await new Promise((resolve) => server.close(resolve));

console.log(" Server closed. No new connections accepted.");

if (agenda) {

await agenda.stop();

console.log(" Agenda job scheduler stopped.");

}

if (mongoose.connection.readyState === 1) {

await mongoose.disconnect();

console.log(" MongoDB disconnected.");

}

console.log(" Graceful shutdown complete. Exiting.");

process.exit(0);

} catch (err) {

console.error(" Error during shutdown:", err);

process.exit(1);

}

};

process.on("SIGTERM", shutdown);

process.on("SIGINT", shutdown);

startApp();" and this is the health check failure "Attempt #1 failed with service unavailable. Continuing to retry for 4m49s Attempt #2 failed with service unavailable. ." I would be glad to get a response to resolve this issue

$10 Bounty

7 Replies

Railway
BOT

3 months ago

Hey there! We've found the following might help you get unblocked faster:

If you find the answer from one of these, please let us know by solving the thread!


mjablonski
PRO

3 months ago

Please try to use server.listen(PORT, "::") instead of server.listen(PORT, "0.0.0.0")


Anonymous
HOBBY

3 months ago

Try something like this:

const http = require("http");

const server = http.createServer(app);

// Track startup completion and shutdown state

let isStartingUp = true;

let isShuttingDown = false;

let startupComplete = false;

const startApp = async () => {

try {

await connectMongo();

await startAgenda();

// Only start server after dependencies are ready

server.listen(PORT, "0.0.0.0", () => {

console.logServer running on port ${PORT} [${NODE_ENV}]);

isStartingUp = false;

startupComplete = true;

});

} catch (err) {

console.error("Fatal startup error:", err);

process.exit(1);

}

};

// Enhanced health check endpoint

app.get(["/health", "/healthz"], async (req, res) => {

try {

// Check shutdown state first

if (isShuttingDown) {

return res.status(503).json({

status: "shutting_down",

message: "Service is shutting down"

});

}

// Check startup completion

if (isStartingUp && !startupComplete) {

return res.status(503).json({

status: "starting_up",

message: "Service is still starting up"

});

}

// Verify database connection

const mongooseConnectionState = mongoose.connection.readyState;

if (mongooseConnectionState !== 1) { // 1 represents 'connected'

return res.status(503).json({

status: "database_disconnected",

message: "Database connection unavailable"

});

}

// Verify agenda scheduler

if (agenda && !await agenda.running()) {

return res.status(503).json({

status: "scheduler_not_running",

message: "Job scheduler not running"

});

}

// All checks passed

res.json({

status: "ok",

uptime: process.uptime(),

timestamp: new Date().toISOString()

});

} catch (error) {

console.error("Health check failed:", error);

res.status(503).json({

status: "error",

message: "Health check failed",

error: error.message

});

}

});

const shutdown = async (signal) => {

if (isShuttingDown) return;

isShuttingDown = true;

try {

await new Promise((resolve) => server.close(resolve));

if (agenda) {

await agenda.stop();

}

if (mongoose.connection.readyState === 1) {

await mongoose.disconnect();

}

console.log("Graceful shutdown complete. Exiting.");

process.exit(0);

} catch (err) {

console.error("Error during shutdown:", err);

process.exit(1);

}

};


The health check failure on Railway is caused by using the wrong IP binding in your Express server. Railway's platform requires servers to bind to :: (IPv6 wildcard) instead of 0.0.0.0 (IPv4 only) to be properly accessible.
Simply change your server.listen line from server.listen(PORT, "0.0.0.0", () => { to server.listen(PORT, "::", () => { and ensure you're using Railway's provided PORT environment variable with const PORT = process.env.PORT || 3000. This single change allows Railway's health check system to successfully reach your endpoints, as the :: binding accepts both IPv4 and IPv6 connections which Railway's infrastructure requires for routing traffic to your application.


mjablonski

Please try to use server.listen(PORT, "::") instead of server.listen(PORT, "0.0.0.0")

debuck1718
HOBBYOP

3 months ago

i have tried but it didn't work "const server = http.createServer(app);

let isShuttingDown = false;

const startApp = async () => {

try {

await connectMongo();

await startAgenda();

// Fix: bind to "::" instead of "0.0.0.0"

server.listen(PORT, "::", () => {

console.log Server running on port ${PORT} [${NODE_ENV}]);

if (isProd && process.env.RENDER_EXTERNAL_URL) {

setInterval(async () => {

try {

await fetch(process.env.RENDER_EXTERNAL_URL);

console.log(" Self-ping successful:", new Date().toISOString());

} catch (err) {

console.error(" Self-ping failed:", err.message);

}

}, 5 60 1000);

}

});

} catch (err) {

console.error(" Fatal startup error:", err);

process.exit(1);

}

};

// Root + health

app.get("/", (req, res) => {

res.status(200).send("SmartStudentAct API is running ");

});

app.get(["/health", "/healthz"], (req, res) => {

res.status(200).json({

status: "ok",

uptime: process.uptime(),

timestamp: new Date().toISOString(),

});

});

// Graceful shutdown

const shutdown = async (signal) => {

if (isShuttingDown) return;

isShuttingDown = true;

console.log\n Received ${signal}, starting graceful shutdown...);

try {

await new Promise((resolve) => server.close(resolve));

console.log(" Server closed. No new connections accepted.");

if (agenda) {

await agenda.stop();

console.log(" Agenda job scheduler stopped.");

}

if (mongoose.connection.readyState === 1) {

await mongoose.disconnect();

console.log(" MongoDB disconnected.");

}

console.log(" Graceful shutdown complete. Exiting.");

process.exit(0);

} catch (err) {

console.error(" Error during shutdown:", err);

process.exit(1);

}

};

process.on("SIGTERM", shutdown);

process.on("SIGINT", shutdown);

startApp();"


Try something like this:const http = require("http");const server = http.createServer(app);// Track startup completion and shutdown statelet isStartingUp = true;let isShuttingDown = false;let startupComplete = false;const startApp = async () => {try {await connectMongo();await startAgenda();// Only start server after dependencies are readyserver.listen(PORT, "0.0.0.0", () => {console.logServer running on port ${PORT} [${NODE_ENV}]);isStartingUp = false;startupComplete = true;});} catch (err) {console.error("Fatal startup error:", err);process.exit(1);}};// Enhanced health check endpointapp.get(["/health", "/healthz"], async (req, res) => {try {// Check shutdown state firstif (isShuttingDown) {return res.status(503).json({status: "shutting_down",message: "Service is shutting down"});}// Check startup completionif (isStartingUp && !startupComplete) {return res.status(503).json({status: "starting_up",message: "Service is still starting up"});}// Verify database connectionconst mongooseConnectionState = mongoose.connection.readyState;if (mongooseConnectionState !== 1) { // 1 represents 'connected'return res.status(503).json({status: "database_disconnected",message: "Database connection unavailable"});}// Verify agenda schedulerif (agenda && !await agenda.running()) {return res.status(503).json({status: "scheduler_not_running",message: "Job scheduler not running"});}// All checks passedres.json({status: "ok",uptime: process.uptime(),timestamp: new Date().toISOString()});} catch (error) {console.error("Health check failed:", error);res.status(503).json({status: "error",message: "Health check failed",error: error.message});}});const shutdown = async (signal) => {if (isShuttingDown) return;isShuttingDown = true;try {await new Promise((resolve) => server.close(resolve));if (agenda) {await agenda.stop();}if (mongoose.connection.readyState === 1) {await mongoose.disconnect();}console.log("Graceful shutdown complete. Exiting.");process.exit(0);} catch (err) {console.error("Error during shutdown:", err);process.exit(1);}};

debuck1718
HOBBYOP

3 months ago

I tried yours too it didn't work. health failure"

const server = http.createServer(app);
let isShuttingDown = false;

// Main startup function
const startApp = async () => {
  try {
    await connectMongo();
    await startAgenda();
    server.listen(PORT, "0.0.0.0", () => {
      console.log(`Server running on port ${PORT}`);
    });
  } catch (err) {
    console.error("Fatal startup error:", err);
    process.exit(1);
  }
};

// --- Health Check Endpoint ---
app.get(["/health", "/healthz"], async (req, res) => {
  try {
    if (isShuttingDown) {
      return res.status(503).json({
        status: "shutting_down",
        message: "Service is shutting down",
      });
    }

    const mongooseConnectionState = mongoose.connection.readyState;
    if (mongooseConnectionState !== 1) { // 1 represents 'connected'
      return res.status(503).json({
        status: "database_disconnected",
        message: "Database connection unavailable",
      });
    }

    // You may need to await agenda.running() if it's an async function
    if (agenda && !(await agenda.running())) {
      return res.status(503).json({
        status: "scheduler_not_running",
        message: "Job scheduler not running",
      });
    }

    // All checks passed
    res.status(200).json({
      status: "ok",
      uptime: process.uptime(),
      timestamp: new Date().toISOString(),
    });
  } catch (error) {
    console.error("Health check failed:", error);
    res.status(503).json({
      status: "error",
      message: "Health check failed due to an internal error.",
      error: error.message,
    });
  }
});

// --- Graceful Shutdown ---
const shutdown = async (signal) => {
  if (isShuttingDown) return;
  isShuttingDown = true;
  console.log(`\n Received ${signal}, starting graceful shutdown...`);
  try {
    await new Promise((resolve) => server.close(resolve));
    if (agenda) await agenda.stop();
    if (mongoose.connection.readyState === 1) await mongoose.disconnect();
    console.log(" Graceful shutdown complete. Exiting.");
    process.exit(0);
  } catch (err) {
    console.error(" Error during shutdown:", err);
    process.exit(1);
  }
};

process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);

startApp();

"
Attempt #1 failed with service unavailable. Continuing to retry for 4m49s

Attempt #2 failed with service unavailable. Continuing to retry for 4m44s

Attempt #3 failed with service unavailable. Continuing to retry for 4m36s

Attempt #4 failed with service unavailable. Continuing to retry for 4m32s

Attempt #5 failed with service unavailable. Continuing to retry for 4m23s

Attempt #6 failed with service unavailable. Continuing to retry for 4m7s

Attempt #7 failed with service unavailable. Continuing to retry for 3m36s

Attempt #8 failed with service unavailable. Continuing to retry for 3m6s

Attempt #9 failed with service unavailable. Continuing to retry for 2m35s

Attempt #10 failed with service unavailable. Continuing to retry for 2m5s

Attempt #11 failed with service unavailable. Continuing to retry for 1m35s

Attempt #12 failed with service unavailable. Continuing to retry for 1m4s

Attempt #13 failed with service unavailable. Continuing to retry for 34s

Attempt #14 failed with service unavailable. Continuing to retry for 3s

1/1 replicas never became healthy!

Healthcheck failed!


dostogircse171

The health check failure on Railway is caused by using the wrong IP binding in your Express server. Railway's platform requires servers to bind to :: (IPv6 wildcard) instead of 0.0.0.0 (IPv4 only) to be properly accessible. Simply change your server.listen line from server.listen(PORT, "0.0.0.0", () => { to server.listen(PORT, "::", () => { and ensure you're using Railway's provided PORT environment variable with const PORT = process.env.PORT || 3000. This single change allows Railway's health check system to successfully reach your endpoints, as the :: binding accepts both IPv4 and IPv6 connections which Railway's infrastructure requires for routing traffic to your application.

debuck1718
HOBBYOP

3 months ago

I tried it but the health failed. here's the server.js "const http = require("http");

const mongoose = require("mongoose");

const Agenda = require("agenda");

const fetch = require("node-fetch");

const { app, eventBus } = require("./app");

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

const MONGO_URI = process.env.MONGODB_URI;

const NODE_ENV = process.env.NODE_ENV || "development";

const isProd = NODE_ENV === "production";

const connectMongo = async () => {

try {

console.log(" Connecting to MongoDB...");

await mongoose.connect(MONGO_URI);

console.log(" MongoDB connected successfully!");

} catch (err) {

console.error(" MongoDB connection error:", err);

throw err;

}

};

let agenda;

const startAgenda = async () => {

try {

agenda = new Agenda({ db: { address: MONGO_URI, collection: "agendaJobs" } });

agenda.define("test job", async () => {

console.log Running test job at ${new Date().toISOString()});

});

await agenda.start();

await agenda.every("1 minute", "test job");

console.log(" Agenda job scheduler started!");

} catch (err) {

console.error(" Agenda startup error:", err);

throw err;

}

};

const server = http.createServer(app);

let isShuttingDown = false;

const startApp = async () => {

try {

await connectMongo();

await startAgenda();

// Fix: bind to "::" instead of "0.0.0.0"

server.listen(PORT, "::", () => {

console.log Server running on port ${PORT} [${NODE_ENV}]);

if (isProd && process.env.RENDER_EXTERNAL_URL) {

setInterval(async () => {

try {

await fetch(process.env.RENDER_EXTERNAL_URL);

console.log(" Self-ping successful:", new Date().toISOString());

} catch (err) {

console.error(" Self-ping failed:", err.message);

}

}, 5 60 1000);

}

});

} catch (err) {

console.error(" Fatal startup error:", err);

process.exit(1);

}

};

// Root + health

app.get("/", (req, res) => {

res.status(200).send("SmartStudentAct API is running ");

});

app.get(["/health", "/healthz"], (req, res) => {

res.status(200).json({

status: "ok",

uptime: process.uptime(),

timestamp: new Date().toISOString(),

});

});

// Graceful shutdown

const shutdown = async (signal) => {

if (isShuttingDown) return;

isShuttingDown = true;

console.log\n Received ${signal}, starting graceful shutdown...);

try {

await new Promise((resolve) => server.close(resolve));

console.log(" Server closed. No new connections accepted.");

if (agenda) {

await agenda.stop();

console.log(" Agenda job scheduler stopped.");

}

if (mongoose.connection.readyState === 1) {

await mongoose.disconnect();

console.log("MongoDB disconnected.");

}

console.log(" Graceful shutdown complete. Exiting.");

process.exit(0);

} catch (err) {

console.error("Error during shutdown:", err);

process.exit(1);

}

};

process.on("SIGTERM", shutdown);

process.on("SIGINT", shutdown);

startApp();

"

Attempt #1 failed with service unavailable. Continuing to retry for 4m59s

Attempt #2 failed with service unavailable. Continuing to retry for 4m55s

Attempt #3 failed with service unavailable. Continuing to retry for 4m43s

Attempt #4 failed with service unavailable. Continuing to retry for 4m39s

Attempt #5 failed with service unavailable. Continuing to retry for 4m20s


Loading...