Healthcheck not working with Django
tylerasselin
HOBBYOP

6 months ago

Hello - I have been unable to get my health check working. I have added "healthcheck.railway.app" to my allowed hosts. I have a port configured. The endpoint works when hit on a deployment that makes it through if I remove the health check: www.rosternerd.com/health

I've tried configuring it via UI and railway.toml. I'm sure there's some configuration issue here, but I have not been able to identify it. Thanks!

2025-09-02T21:39:04.043911367Z [inf] ====================

2025-09-02T21:39:04.043920649Z [inf] Starting Healthcheck

2025-09-02T21:39:04.043926167Z [inf] ====================

2025-09-02T21:39:04.043933220Z [inf] 

2025-09-02T21:39:04.043938340Z [inf] Path: /health/

2025-09-02T21:39:04.043943407Z [inf] Retry window: 5m0s

2025-09-02T21:39:04.043948658Z [inf]

2025-09-02T21:39:14.125352706Z [inf] Attempt #1 failed with service unavailable. Continuing to retry for 4m49s

2025-09-02T21:39:25.161961198Z [inf] Attempt #2 failed with service unavailable. Continuing to retry for 4m38s

2025-09-02T21:39:28.281132780Z [inf] Attempt #3 failed with service unavailable. Continuing to retry for 4m35s

2025-09-02T21:39:32.601830818Z [inf] Attempt #4 failed with service unavailable. Continuing to retry for 4m31s

2025-09-02T21:39:40.657547263Z [inf] Attempt #5 failed with service unavailable. Continuing to retry for 4m23s

2025-09-02T21:39:56.705261280Z [inf] Attempt #6 failed with service unavailable. Continuing to retry for 4m7s

2025-09-02T21:40:26.750243862Z [inf] Attempt #7 failed with service unavailable. Continuing to retry for 3m37s

2025-09-02T21:40:56.814667397Z [inf] Attempt #8 failed with service unavailable. Continuing to retry for 3m7s

2025-09-02T21:41:26.866402479Z [inf] Attempt #9 failed with service unavailable. Continuing to retry for 2m37s

2025-09-02T21:41:56.927317264Z [inf] Attempt #10 failed with service unavailable. Continuing to retry for 2m7s

2025-09-02T21:42:27.088559991Z [inf] Attempt #11 failed with service unavailable. Continuing to retry for 1m36s

2025-09-02T21:42:57.139905277Z [inf] Attempt #12 failed with service unavailable. Continuing to retry for 1m6s

2025-09-02T21:43:27.188043032Z [inf] Attempt #13 failed with service unavailable. Continuing to retry for 36s

2025-09-02T21:43:57.240070228Z [inf] Attempt #14 failed with service unavailable. Continuing to retry for 6s

2025-09-02T21:43:57.285619420Z [inf]

2025-09-02T21:43:57.285659999Z [inf] 1/1 replicas never became healthy!

2025-09-02T21:43:57.285666841Z [inf] Healthcheck failed!

Under Review$10 Bounty

0 Threads mention this feature

Pinned Solution

tylerasselin
HOBBYOP

6 months ago

I got this working. The issue was that my project had the Django setting SECURE_SSL_REDIRECT set to true by default. That being the case, the health check's HTTP requests were receiving 302 redirect codes as my app was redirecting to HTTPS. Once I disabled SECURE_SSL_REDIRECT the health check started working.

For posterity: After removing the SECURE_SSL_REDIRECT setting, all of the health check endpoints that I set up started working. That means that a 200 OK is not required. It also means that HTML is fine.

I appreciate all of the helpful suggestions!

16 Replies

Railway
BOT

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


6 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 6 months ago


irazvan2745
FREE

6 months ago

what’s the health check config?


tylerasselin
HOBBYOP

6 months ago

Uploaded a screenshot of what I've tried in the UI. Obviously it's purple because I didn't actually deploy it since it was just for the sake of the screenshot. I've tried /health and /health/

I've also tried to configure it on my railway.toml

[deploy]
startCommand = "./start.sh"
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10
healthcheckPath = "/health/"
healthcheckTimeout = 300

Attachments


irazvan2745
FREE

6 months ago

Try removing the railway config file, and instead only use railway ui


tylerasselin
HOBBYOP

6 months ago

I tried UI only many many many times before ever attempting via the railway.toml. Neither work.


tylerasselin
HOBBYOP

6 months ago

Oh do you mean do not use the railway.toml any of the configs? I can try that


irazvan2745
FREE

6 months ago

Im pretty sure the health check endpoint should only output “OK”, try making it output that instead of html


tylerasselin
HOBBYOP

6 months ago

I can build an endpoint that returns a 200 and OK, but the docs don't say that is specifically needed. If that works, maybe I can submit a doc update request.

I am also going to test UI-only config without my railway.toml.


tylerasselin
HOBBYOP

6 months ago

I built an endpoint, /railway-deploy-health/ , that returns an empty 200:

@require_GET
def railway_deploy_health(request):
    """Simple healthcheck endpoint for Railway deployment that returns only 200 OK."""
    return HttpResponse(status=200)

 path("railway-deploy-health/", railway_deploy_health, name="railway_deploy_health"),

Updated my railway.toml with that endpoint as the healthcheckPath:

[build] builder = "DOCKERFILE" [deploy] startCommand = "./start.sh" restartPolicyType = "ON_FAILURE" restartPolicyMaxRetries = 10 healthcheckPath = "/railway-deploy-health/" healthcheckTimeout = 300 [services.web] source = "." builder = "DOCKERFILE" startCommand = "./start.sh" # Health check configuration - waits for django-health-check to return 200 # Timeout allows for database migrations and service startup healthcheckPath = "/railway-deploy-health/" healthcheckTimeout = 300 restartPolicyType = "ON_FAILURE" restartPolicyMaxRetries = 10 [services.worker] source = "." builder = "DOCKERFILE" startCommand = "celery -A config.celery_app worker -l info --concurrency=2" [services.beat] source = "." builder = "DOCKERFILE" startCommand = "celery -A config.celery_app beat -l info"

The build completes and starts the health check, but fails:

2025-09-03T00:38:17.281512726Z [inf] importing to docker

2025-09-03T00:38:29.576556038Z [inf] importing to docker

2025-09-03T00:38:38.596309450Z [inf] Build time: 29.32 seconds

2025-09-03T00:38:59.913306491Z [inf]

2025-09-03T00:38:59.913351633Z [inf] ====================

2025-09-03T00:38:59.913356668Z [inf] Starting Healthcheck

2025-09-03T00:38:59.913361166Z [inf] ====================

2025-09-03T00:38:59.913365678Z [inf] 

2025-09-03T00:38:59.913369348Z [inf] Path: /railway-deploy-health/

2025-09-03T00:38:59.913373028Z [inf] Retry window: 5m0s

2025-09-03T00:38:59.913378730Z [inf]

2025-09-03T00:39:09.987477679Z [inf] Attempt #1 failed with service unavailable. Continuing to retry for 4m49s

2025-09-03T00:39:20.024190309Z [inf] Attempt #2 failed with service unavailable. Continuing to retry for 4m39s

2025-09-03T00:39:22.272263749Z [inf] Attempt #3 failed with service unavailable. Continuing to retry for 4m37s

2025-09-03T00:39:26.371656359Z [inf] Attempt #4 failed with service unavailable. Continuing to retry for 4m33s

2025-09-03T00:39:34.418375267Z [inf] Attempt #5 failed with service unavailable. Continuing to retry for 4m25s

2025-09-03T00:39:50.502391870Z [inf] Attempt #6 failed with service unavailable. Continuing to retry for 4m9s

2025-09-03T00:40:20.615050397Z [inf] Attempt #7 failed with service unavailable. Continuing to retry for 3m39s

Despite the server running:

2025-09-03T00:38:58.000000000Z [inf] Starting Container

2025-09-03T00:39:16.371057708Z [inf]

2025-09-03T00:39:16.371064754Z [inf] === Starting Gunicorn ===

2025-09-03T00:39:16.371070355Z [inf] Binding to: 0.0.0.0:8080

2025-09-03T00:39:16.933354939Z [err] [2025-09-03 00:39:16 +0000] [1] [INFO] Starting gunicorn 23.0.0

2025-09-03T00:39:16.933361698Z [err] [2025-09-03 00:39:16 +0000] [1] [INFO] Listening at: http://0.0.0.0:8080 (1)

2025-09-03T00:39:16.933366101Z [err] [2025-09-03 00:39:16 +0000] [1] [INFO] Using worker: sync

2025-09-03T00:39:16.942190005Z [err] [2025-09-03 00:39:16 +0000] [51] [INFO] Booting worker with pid: 51

2025-09-03T00:39:17.022531808Z [err] [2025-09-03 00:39:17 +0000] [52] [INFO] Booting worker with pid: 52


case
PRO

6 months ago

In case it's helpful, this is how I have my healthchecks configured, in my railway.json file:

  "deploy": {
    "healthcheckPath": "/healthz",
    "healthcheckTimeout": 60,

…and this is the code that responds to requests there:

if (req.url === "/healthz") {
      res.writeHead(200, { "Content-Type": "text/plain" });
      res.end("OK");
    }

https://stackoverflow.com/questions/43380939/where-does-the-convention-of-using-healthz-for-application-health-checks-come-f


irazvan2745
FREE

6 months ago

"/healthz" is a 404
www.rosternerd.com/healthz


irazvan2745

"/healthz" is a 404 www.rosternerd.com/healthz

tylerasselin
HOBBYOP

6 months ago

I don't have /healthz set up so you're going to get a 404. My endpoint is currently /railway-deploy-health. I can set up /healthz if it's a requirement, but I don't see if the docs where it says that's what it has to be called.


tylerasselin
HOBBYOP

6 months ago

I got this working. The issue was that my project had the Django setting SECURE_SSL_REDIRECT set to true by default. That being the case, the health check's HTTP requests were receiving 302 redirect codes as my app was redirecting to HTTPS. Once I disabled SECURE_SSL_REDIRECT the health check started working.

For posterity: After removing the SECURE_SSL_REDIRECT setting, all of the health check endpoints that I set up started working. That means that a 200 OK is not required. It also means that HTML is fine.

I appreciate all of the helpful suggestions!


case
PRO

6 months ago

To close the loop on /healthz - no it's not required to do it this way, it's just a convention that Google uses.


case

To close the loop on /healthz - no it's not required to do it this way, it's just a convention that Google uses.

tylerasselin
HOBBYOP

6 months ago

Thanks for the update. I did read the link you provided for that additional context. I'm actually going to keep the /healthz endpoint for railway to use for these health checks and keep it separate from my other /health endpoint which has more going on than is needed for these railway checks. Thanks again!


janheussner
PRO

6 months ago

SECURE_REDIRECT_EXEMPT = [r'^healthz/$'] 

This has solved the issue for me. So you dont have to deactivate it completly.


Loading...