Liveness probe
HTTP POST
Kubernetes
Health check
Application monitoring

Liveness probe with http post

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Kubernetes supports liveness probes, but it does not support an HTTP POST probe type. For HTTP-based health checks, the built-in probe uses httpGet, which means the practical answer is to expose an idempotent GET health endpoint or choose a different probe mechanism.

What Kubernetes Actually Supports

Today the kubelet supports these built-in liveness probe styles:

  • 'httpGet'
  • 'tcpSocket'
  • 'exec'
  • 'grpc'

Notice what is missing: there is no httpPost field. If you need the kubelet to make an HTTP request on its own, the native choice is GET.

A standard HTTP liveness probe looks like this:

yaml
1apiVersion: v1
2kind: Pod
3metadata:
4  name: web-app
5spec:
6  containers:
7    - name: app
8      image: nginx:1.27
9      ports:
10        - containerPort: 8080
11      livenessProbe:
12        httpGet:
13          path: /healthz
14          port: 8080
15        initialDelaySeconds: 10
16        periodSeconds: 10
17        timeoutSeconds: 2
18        failureThreshold: 3

That is the supported pattern for an HTTP health check. If the endpoint stops returning a successful response, the kubelet restarts the container.

Why POST Is Not a Good Fit for Liveness

Liveness checks should answer one narrow question: "Is this process healthy enough to keep running?" The safest way to ask that question is with an idempotent read-style operation.

An HTTP POST is usually a poor match because it often:

  • changes server state
  • requires a request body
  • depends on business logic rather than process health
  • becomes harder to reason about when retried repeatedly

That design tension is probably why Kubernetes exposes GET for HTTP probes instead of a generic request builder. A health probe should be cheap, predictable, and side-effect free.

If your application only reports health through a POST endpoint, that is often a signal that the health contract should be redesigned. Add a dedicated GET /healthz or GET /livez endpoint that does the minimal internal checks needed for liveness.

Better Alternatives Than Forcing POST

The cleanest solution is to expose a dedicated GET endpoint for health:

python
1from flask import Flask, jsonify
2
3app = Flask(__name__)
4
5@app.get("/healthz")
6def healthz():
7    return jsonify(status="ok"), 200

Then Kubernetes can call that endpoint with a normal httpGet probe and you avoid putting state-changing behavior behind the liveness check.

If you truly must run a POST, the only built-in workaround is an exec probe that performs the request from inside the container:

yaml
1apiVersion: v1
2kind: Pod
3metadata:
4  name: custom-probe
5spec:
6  containers:
7    - name: app
8      image: curlimages/curl:8.7.1
9      command: ["sh", "-c", "sleep infinity"]
10      livenessProbe:
11        exec:
12          command:
13            - sh
14            - -c
15            - 'curl -fsS -X POST http://127.0.0.1:8080/internal-health'
16        initialDelaySeconds: 10
17        periodSeconds: 15

This works technically, but it has tradeoffs:

  • the image must contain curl or a similar client
  • the probe is more expensive than httpGet
  • failures may reflect shell or networking details instead of pure app health
  • a state-changing POST can still make restarts harder to reason about

Use this only when changing the application contract is not feasible.

When Other Probe Types Make More Sense

Sometimes the right answer is not HTTP at all. If you only need to know whether a process is listening, tcpSocket may be enough. If your service already implements the gRPC health checking protocol, a native grpc probe is cleaner than wrapping that logic in a custom HTTP route.

Use exec when the application can best report health through a local command or file check. For example, some workloads can expose health by checking a pid file, querying a local socket, or verifying a critical dependency with a shell command.

The important point is that liveness should stay narrowly scoped. Do not turn it into a miniature functional test of the whole application stack.

Common Pitfalls

The biggest pitfall is assuming Kubernetes has an httpPost liveness probe field. It does not. Trying to invent one in YAML only produces an invalid manifest.

Another common mistake is using a business endpoint as the health endpoint. If the route depends on a write transaction, a queue mutation, or a large external dependency chain, it becomes fragile and may cause unnecessary restarts. Teams also sometimes use exec with curl -X POST as a permanent design rather than as a fallback. That increases complexity and hides the real issue, which is usually that the application lacks a proper read-only health endpoint.

Summary

  • Kubernetes does not support a native HTTP POST liveness probe.
  • The built-in HTTP probe type is httpGet, so a dedicated GET health endpoint is the best solution.
  • 'POST is a poor liveness contract because probes should be idempotent and free of side effects.'
  • If you cannot change the app, an exec probe can run curl -X POST inside the container as a workaround.
  • Consider tcpSocket or grpc probes when those protocols match the application's health model more naturally.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.