Node.js App gets SIGTERM after successful start and healthcheck

sharulwardana
FREE

2 months ago

Hello Railway team, I'm facing a persistent issue where my Node.js application is being terminated by a SIGTERM signal, even though the logs show a successful startup and a successful initial health check response.

The Problem:

My application log consistently shows this sequence:

  1. Database connection successful.

  2. Server running on http://0.0.0.0:8080

  3. Health check endpoint was hit.

  4. npm error signal SIGTERM

  5. Stopping Container

What I've already tried and configured:

  • My start command is correctly set to npm run start.

  • My Healthcheck Path is correctly set to /health, and my app has a GET /health route that returns a 200 status.

  • I've confirmed the database connects successfully before the server starts.

  • The issue persists even when I deploy a minimal, barebones "hello world" Express server with no other dependencies or routes besides /health.

It seems like something on the platform level is terminating the process after the first successful health check. Could you please take a look at my deployment?

$10 Bounty

13 Replies

Railway
BOT

2 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!


2 months ago

This thread has been marked as public for community involvement, as it does not contain any sensitive or personal information. Any further activity in this thread will be visible to everyone.

Status changed to Open brody 2 months ago


sharulwardana
FREE

2 months ago

Hi Brody, thank you for the explanation about the SIGTERM logs.

However, the problem is still happening with my new deployments. The service becomes unreachable and my frontend gets a 502 Bad Gateway error shortly after the server successfully starts.

My logs show a successful start ( Server running...), but then the service is stopped by a SIGTERM signal. I believe this is due to a failing health check, even though I've configured everything correctly.

For your information, I have already tried all of these steps:

  • Confirmed the database connects successfully before the server starts.

  • The user_sessions table exists in the database.

  • The "Start Command" in my service settings is set to npm run start.

  • The "Healthcheck Path" is set to /health, and my server.js has this route.

  • The issue still happens even when I deploy a minimal "hello world" Express server with no other code.

Since this problem persists even with a minimal server and all standard configurations are correct, could you please investigate from your side to see why the health checks might be failing or why my container is being terminated?

Thank you for your help.


shxkm
PRO

2 months ago

I don't know if Node.js has a comparable "allowed hosts" setting (for example, in Django that's ALLOWED_HOSTS), but did you make sure those include healthcheck.railway.app?


shxkm

I don't know if Node.js has a comparable "allowed hosts" setting (for example, in Django that's ALLOWED_HOSTS), but did you make sure those include healthcheck.railway.app?

sharulwardana
FREE

2 months ago

Hi team,

I'm following up on my issue. I've tried one last suggestion from the community, which was to add healthcheck.railway.app to my CORS allowedOrigins list.

Unfortunately, the issue remains exactly the same. The logs show a perfect startup, followed by a SIGTERM signal from the platform.

At this point, we have definitively ruled out any configuration or code issues on my end. This appears to be a platform-level problem with how the health check system is interacting with my service.

Could you please escalate this issue and investigate the internal platform logs for my service? My project is completely blocked.

Thank you for your time.


pal
HOBBY

2 months ago

I assume you don't have a public repo of the project you can share?


pal

I assume you don't have a public repo of the project you can share?

sharulwardana
FREE

2 months ago

Hi Pal, thanks for getting back to me.

I've made the repository public as you suggested. You can access it here: https://github.com/sharulwardana/dpstore-backend

Unfortunately, the issue remains exactly the same. The container still receives a SIGTERM signal about 30-60 seconds after a successful startup and health check.

Here is a summary of what has been tried so far without success:

1. CORS Configuration: Confirmed that my Netlify frontend URL and the Railway health check URL are correctly listed in the allowedOrigins.

2. Memory Optimization: Added --optimize_for_size --max_old_space_size=460 to the start command in package.json. The logs show this was applied, but the outcome didn't change.

3. Environment Variables: I have double-checked and ensured that all variables from my local .env file (especially JWT_SECRET and DATABASE_URL) are correctly set in the Railway project's "Variables" tab.

Even after all these steps, the latest log shows the exact same pattern: successful start, successful health check, and then a SIGTERM.

Here is the most recent log after applying the memory optimization flags:

Starting Container

npm warn config production Use --omit=dev instead.

> dpstore-backend@1.0.0 start

> node --optimize_for_size --max_old_space_size=460 server.js

[dotenv@17.2.1] injecting env (0) from .env -- tip: observe env with Radar: https://dotenvx.com/radar

Starting DPStore Backend Server...

Environment check:

- DATABASE_URL exists: true

- JWT_SECRET exists: true

- SESSION_SECRET exists: true

- NODE_ENV: production

- PORT: 8080

Creating database pool...

Loading route modules...

Route modules loaded successfully

Initiating server startup sequence...

Testing database connection...

Attempting to connect to database (attempt 1)...

Database connection successful.

Database query test successful: { current_time: 2025-08-11T04:45:00.411Z }

Database is ready. Starting web server...

Configuring CORS...

CORS configured

Setting up middleware...

Setting up session middleware...

Session middleware configured

Setting up API routes...

API routes configured

Server running successfully on http://0.0.0.0:8080

Health check available at: http://0.0.0.0:8080/health

API endpoints available at: http://0.0.0.0:8080/api

DPStore Backend is ready to serve requests!

CORS request from origin: undefined

[INCOMING REQUEST] 2025-08-11T04:45:01.393Z | GET /health | From: 100.64.0.2

Health check called from: RailwayHealthCheck/1.0

Health check headers: {

"host": "healthcheck.railway.app",

"user-agent": "RailwayHealthCheck/1.0",

"accept-encoding": "gzip",

"connection": "close"

}

Sending health check response: {

"status": "OK",

"message": "Server is healthy",

"timestamp": "2025-08-11T04:45:01.394Z",

"uptime": "1s"

}

Health check response sent successfully

Stopping Container

npm error path /app

npm error command failed

npm error signal SIGTERM

npm error command sh -c node server.js

npm error A complete log of this run can be found in: /root/.npm/_logs/2025-08-11T04_40_46_269Z-debug-0.log

Server heartbeat - uptime: 30s

Since the repository is now public, could you or someone from the Railway team please take a look? I'm completely blocked at this point and suspect it might be a platform-level interaction with my setup.

Thank you for your time and help.


sharulwardana

Hi Pal, thanks for getting back to me.I've made the repository public as you suggested. You can access it here: https://github.com/sharulwardana/dpstore-backendUnfortunately, the issue remains exactly the same. The container still receives a SIGTERM signal about 30-60 seconds after a successful startup and health check.Here is a summary of what has been tried so far without success:1. CORS Configuration: Confirmed that my Netlify frontend URL and the Railway health check URL are correctly listed in the allowedOrigins.2. Memory Optimization: Added --optimize_for_size --max_old_space_size=460 to the start command in package.json. The logs show this was applied, but the outcome didn't change.3. Environment Variables: I have double-checked and ensured that all variables from my local .env file (especially JWT_SECRET and DATABASE_URL) are correctly set in the Railway project's "Variables" tab.Even after all these steps, the latest log shows the exact same pattern: successful start, successful health check, and then a SIGTERM.Here is the most recent log after applying the memory optimization flags:Starting Containernpm warn config production Use --omit=dev instead.> dpstore-backend@1.0.0 start> node --optimize_for_size --max_old_space_size=460 server.js[dotenv@17.2.1] injecting env (0) from .env -- tip: observe env with Radar: https://dotenvx.com/radarStarting DPStore Backend Server...Environment check:- DATABASE_URL exists: true- JWT_SECRET exists: true- SESSION_SECRET exists: true- NODE_ENV: production- PORT: 8080Creating database pool...Loading route modules...Route modules loaded successfullyInitiating server startup sequence...Testing database connection...Attempting to connect to database (attempt 1)...Database connection successful.Database query test successful: { current_time: 2025-08-11T04:45:00.411Z }Database is ready. Starting web server...Configuring CORS...CORS configuredSetting up middleware...Setting up session middleware...Session middleware configuredSetting up API routes...API routes configuredServer running successfully on http://0.0.0.0:8080Health check available at: http://0.0.0.0:8080/healthAPI endpoints available at: http://0.0.0.0:8080/apiDPStore Backend is ready to serve requests!CORS request from origin: undefined[INCOMING REQUEST] 2025-08-11T04:45:01.393Z | GET /health | From: 100.64.0.2Health check called from: RailwayHealthCheck/1.0Health check headers: {"host": "healthcheck.railway.app","user-agent": "RailwayHealthCheck/1.0","accept-encoding": "gzip","connection": "close"}Sending health check response: {"status": "OK","message": "Server is healthy","timestamp": "2025-08-11T04:45:01.394Z","uptime": "1s"}Health check response sent successfullyStopping Containernpm error path /appnpm error command failednpm error signal SIGTERMnpm error command sh -c node server.jsnpm error A complete log of this run can be found in: /root/.npm/_logs/2025-08-11T04_40_46_269Z-debug-0.logServer heartbeat - uptime: 30sSince the repository is now public, could you or someone from the Railway team please take a look? I'm completely blocked at this point and suspect it might be a platform-level interaction with my setup.Thank you for your time and help.

smolpaw
HOBBY

2 months ago

Does it still work when you remove the healthcheck from service in your railway dashboard ?


smolpaw

Does it still work when you remove the healthcheck from service in your railway dashboard ?

sharulwardana
FREE

2 months ago

That's a great suggestion, thank you. I have just removed the healthcheck path from my service settings and redeployed it. I will monitor the logs for the next hour to see if the SIGTERM issue still occurs and will report back here.


sharulwardana

That's a great suggestion, thank you. I have just removed the healthcheck path from my service settings and redeployed it. I will monitor the logs for the next hour to see if the SIGTERM issue still occurs and will report back here.

clashing
HOBBY

2 months ago

But removing the healthcheck endopint is not a solution!! Health cheks are there to ensure that your server is up and listening! They are not meant to be a roadblock.

You can check my post on health checkups, & see if that helps or not https://station.railway.com/questions/node-js-service-failing-to-deploy-with-s-dc58e402#mk2w


smolpaw
HOBBY

2 months ago

The goal is to get a successful deployment first, then we know the cause is the healthcheck so we figure out the root cause and a fix for it.


clashing
HOBBY

2 months ago

sharulwardana, you just need to submit a 200 response back from the healthcheckup endpoint, and you are sending a lot of unnecessary information to Railway!

Instead of doing that, just do this:

app.get("/health", async (req, res) => {
  res.status(200).send({
    success: true,
  });
});

This is more than enough!

I am sure that this is not a CHECKUP error because there is no error coming in from the /health in your server. It seems to be something else: most likely to be a database issue. Can you please double-check if all of the DB credentials and all env variables are defined correctly in the setup?

And are you sure that you have not made the service serverless deployment? Navigate to the settings of that deployed Railway service -> Serverless (and make sure that the toggle is not turned on)

This option should be turned off, so that your server could run all the time to handle input requests

Attachments


jitmisra
HOBBY

2 months ago

this is a tricky issue, and your debugging has correctly ruled out your application logic as the cause. When a healthy, minimal app gets a SIGTERM right after starting, the problem almost always points to the deployment environment itself, specifically resource limits.

The Railway Free tier has low memory limits (e.g., under 512MB RAM). Your Node.js application, even a small one, can briefly spike its memory usage right after it starts. If this spike exceeds the plan's limit, Railway's orchestrator will automatically send a SIGTERM signal to terminate the process to ensure platform stability. This happens very quickly, creating the confusing sequence you see: the server starts, passes the initial health check, but is then shut down by the system for exceeding its resource allocation.

How to Confirm and Fix It

  1. Check Your Service Metrics: The best way to confirm this is to watch the Metrics tab for your service immediately after you deploy. You will likely see a sharp spike in the "Memory Usage" graph that hits the red limit line right before the container stops.

  2. Upgrade Your Plan: The most reliable and recommended solution is to upgrade to a paid plan, such as the Hobby plan. This will provide your service with significantly more memory and CPU resources, preventing the startup spike from hitting the limit and allowing your application to run stably.

While you can try optimizing your app to use less memory (for instance, by running your start command directly with node server.js instead of npm run start to reduce npm's overhead), the resource limits on the Free tier are the most likely root cause for this behavior.


jitmisra

this is a tricky issue, and your debugging has correctly ruled out your application logic as the cause. When a healthy, minimal app gets a SIGTERM right after starting, the problem almost always points to the deployment environment itself, specifically resource limits.The Railway Free tier has low memory limits (e.g., under 512MB RAM). Your Node.js application, even a small one, can briefly spike its memory usage right after it starts. If this spike exceeds the plan's limit, Railway's orchestrator will automatically send a SIGTERM signal to terminate the process to ensure platform stability. This happens very quickly, creating the confusing sequence you see: the server starts, passes the initial health check, but is then shut down by the system for exceeding its resource allocation.How to Confirm and Fix ItCheck Your Service Metrics: The best way to confirm this is to watch the Metrics tab for your service immediately after you deploy. You will likely see a sharp spike in the "Memory Usage" graph that hits the red limit line right before the container stops.Upgrade Your Plan: The most reliable and recommended solution is to upgrade to a paid plan, such as the Hobby plan. This will provide your service with significantly more memory and CPU resources, preventing the startup spike from hitting the limit and allowing your application to run stably.While you can try optimizing your app to use less memory (for instance, by running your start command directly with node server.js instead of npm run start to reduce npm's overhead), the resource limits on the Free tier are the most likely root cause for this behavior.

sharulwardana
FREE

2 months ago

like this?


Node.js App gets SIGTERM after successful start and healthcheck - Railway Help Station