Health Checks & Readiness Probes in Keycloak

Health Checks & Readiness Probes in Keycloak

A zero-prior-knowledge guide to the small, constantly repeated questions Keycloak answers about its own condition — and why the difference between "alive" and "ready" can decide whether your login page stays up during an outage.

Imagine a restaurant with a night manager whose only job is to periodically check on the kitchen and answer one simple question for the front-of-house staff: “should we keep sending new orders back there right now?” The manager does not need to know every detail of what a chef is cooking — only whether the kitchen is currently capable of handling more work, or whether it needs a moment before it can safely take on anything new. Keycloak, running as a production service that other systems depend on constantly, needs exactly this same kind of ongoing self-check. This article explains, from first principles, what Health Checks and Readiness Probes in Keycloac actually are, how they differ from each other, and why the infrastructure surrounding Keycloak leans on them so heavily to keep logins running smoothly.

01

Foundations

Core Concepts

Before looking at Keycloak’s specific implementation, it helps to understand the general idea behind health checking, and why “is it running?” is actually a more complicated question than it first sounds.

Why “is it running?” is not one simple question

A server process can technically be running — accepting network connections, responding to some requests — while still being in no condition to handle real traffic correctly. Perhaps its underlying database connection has failed, or it is still finishing its own startup routine. Modern infrastructure needs a more precise vocabulary than a single “up or down” signal, which is exactly why health checking is typically broken into several distinct kinds of checks, each answering a different, specific question.

Liveness: “should this process be restarted?”

A liveness check answers a narrow, blunt question: is this specific running process fundamentally stuck, broken, or unresponsive in a way that no amount of waiting will fix, such that the only sensible remedy is to kill it and start a fresh instance? A failing liveness check is a strong signal that something has gone wrong at a deep, likely unrecoverable level within that particular running instance.

Readiness: “should this process receive new traffic right now?”

A readiness check answers a softer, more temporary question: is this instance currently in a state where it can correctly handle new incoming requests, even if it does not necessarily need to be restarted? A server that has lost its connection to a required database might still be technically alive and capable of eventually recovering, but it should not be sent new login requests it cannot properly complete in the meantime.

Everyday Analogy

Picture a toll booth on a busy highway. A liveness check is like asking, “is there still a working toll booth structure standing at this lane at all, or has it collapsed and needs to be rebuilt from scratch?” A readiness check is like asking, “is the toll booth attendant currently at their window and able to process the next car, or are they on a brief break and cars should be temporarily directed to a different lane?” Both questions matter, but they call for very different responses.

Startup: “has this process finished starting up yet?”

Many modern systems, including Keycloak, also support a distinct startup check, specifically addressing processes that can take a genuinely long time to initialize before they are ready to answer either of the other two questions meaningfully. Without a dedicated startup check, a slow-starting instance might be mistaken for one that has failed liveness, and be repeatedly and unnecessarily restarted before it ever gets the chance to finish starting up properly.

Deep failure

Liveness

Is this instance broken in a way that only a restart can fix?

Temporary state

Readiness

Can this instance correctly handle new traffic right now, this moment?

Initialization

Startup

Has this instance finished its own boot-up process yet?

The consumer

Orchestrators & Load Balancers

Automated systems that ask these questions constantly, and act on the answers without a human involved.

02

Structure

Architecture & Components

Keycloak exposes its health information through a small, dedicated family of endpoints, built on a well-established underlying health-check framework.

The underlying framework

Keycloak is built on the Quarkus application framework, which itself includes a standardized health-check subsystem based on the SmallRye Health specification, a widely used approach in the broader Java ecosystem for exposing exactly this kind of liveness, readiness, and startup information in a consistent, predictable format.

The health endpoint family

Once enabled, Keycloak exposes health information through a small set of dedicated HTTP endpoints, most notably one representing overall liveness, one representing overall readiness, and one representing startup completion, alongside a combined endpoint that reports the aggregate health status across all registered checks at once. Each of these is designed to be queried repeatedly, automatically, and frequently by external systems, rather than by a human manually checking a dashboard.

Individual health check contributors

Behind these top-level endpoints, Keycloak aggregates the results of several individual, more specific health checks — for example, a check confirming database connectivity is functioning correctly. The overall readiness or liveness status reported is effectively a summary of whether all of these individual, more granular checks are currently passing.

Enabling the health subsystem

Keycloak’s health check endpoints are not necessarily active by default in every configuration, and typically need to be explicitly enabled as part of the server’s own configuration, alongside deciding whether these endpoints should be reachable only internally or exposed more broadly, since health information can itself reveal details about the server’s internal state that should not be carelessly exposed to untrusted networks.

flowchart TD
    A["Kubernetes / Orchestrator / Load Balancer"] --> B["Calls Keycloak's /health/live"]
    A --> C["Calls Keycloak's /health/ready"]
    A --> D["Calls Keycloak's /health/started"]
    B --> E["Aggregates internal liveness checks"]
    C --> F["Aggregates internal readiness checks: e.g. Database Connectivity"]
    D --> G["Confirms startup sequence has completed"]
    E --> H["Overall Liveness Status"]
    F --> I["Overall Readiness Status"]
    G --> J["Overall Startup Status"]
    H --> K["Orchestrator decides: restart instance?"]
    I --> L["Load Balancer decides: send traffic here?"]
    

Fig 1 — How Keycloak’s individual health checks roll up into the three top-level probe endpoints external systems actually query.

What matters most here is the separation of concerns: liveness and readiness are reported through genuinely distinct endpoints, precisely because the correct action for a failing liveness check — restart the instance — is very different from the correct action for a failing readiness check — simply stop sending it new traffic for now.

Understanding what actually happens inside Keycloak when one of these endpoints is queried clarifies why the answers can change quickly, and why that is exactly the intended behavior.

What a readiness check actually verifies

When Keycloak’s readiness endpoint is queried, it does not simply confirm the web server process itself is running — it checks whether the specific dependencies Keycloak actually needs in order to correctly process requests, most importantly its underlying database connection, are currently functioning. If that database connection is temporarily unavailable, the readiness check will correctly report a failing status, even though the Keycloak process itself has not crashed and remains technically alive.

Why liveness checks stay deliberately narrow

A liveness check is deliberately designed to be much narrower in scope than a readiness check, typically confirming only that the core process itself has not become deadlocked or otherwise irrecoverably stuck. This narrowness is intentional: a liveness check failing triggers a restart, which is a fairly disruptive action, so it should only fire for problems a restart can genuinely fix, rather than for temporary, external issues like a brief database outage that a restart would not actually resolve any faster.

Everyday Analogy

Think of a delivery driver whose truck engine is running perfectly fine — that is liveness, and it would be pointless to send the truck back to the garage for repairs over it. But if the road ahead is temporarily flooded, the driver simply should not be dispatched down that route right now — that is readiness, a temporary condition that will resolve on its own once the water recedes, without anyone needing to fix the truck itself.

Why startup checks matter separately from liveness

Keycloak, particularly in more complex, clustered deployments, can take a meaningful amount of time to fully initialize — establishing database connections, warming caches, joining a cluster. Without a dedicated startup check, an orchestrator watching only the liveness endpoint might incorrectly conclude a still-initializing instance has failed, and repeatedly restart it before it ever gets a real chance to finish starting, creating a frustrating cycle that never actually resolves.

How the aggregate status is calculated

Each top-level probe endpoint’s overall status is generally determined by combining the results of every individual, more specific check registered under that category. If even one contributing check reports a failure — for example, the database connectivity check specifically — the entire aggregate readiness status reported by Keycloak reflects that failure, even if every other individual check is currently passing correctly.

04

Lifecycle

Data Flow & Lifecycle

Following a single Keycloak instance through a realistic deployment lifecycle shows exactly when each type of probe becomes relevant.

1

A new instance is launched

An orchestrator starts a fresh Keycloak instance, and begins querying its startup endpoint, waiting for it to report that initialization has genuinely completed before treating the instance as a candidate for the other probes at all.

2

Startup completes successfully

Once the startup check reports success, the orchestrator begins regularly querying both the liveness and readiness endpoints going forward, as part of the instance’s normal, ongoing operation.

3

Normal operation: both probes pass

Under healthy conditions, both liveness and readiness consistently report success, and the load balancer continues routing real login traffic to this instance without interruption.

4

A temporary database issue occurs

The underlying database becomes briefly unreachable. The readiness check begins failing, since Keycloak cannot correctly process login requests without it, while the liveness check continues to pass, since the process itself remains fundamentally intact.

5

Traffic is automatically redirected

The load balancer, seeing the failed readiness check, temporarily stops sending new requests to this specific instance, without the orchestrator restarting it, since liveness remains healthy throughout.

6

The database recovers, and so does readiness

Once the database connection is restored, the readiness check begins passing again on its very next scheduled query, and the load balancer resumes sending traffic to this instance automatically, with no manual intervention required at any point.

“Readiness is what lets a system heal itself quietly, by simply routing around a temporary problem, instead of overreacting with an unnecessary restart.”
05

Weighing the Choice

Advantages, Disadvantages & Trade-offs

Relying on health checks and readiness probes is a near-universal practice in production deployments, but configuring them well still involves genuine, deliberate trade-offs.

Advantages

  • Allows infrastructure to automatically detect and route around temporarily unhealthy instances, without requiring constant manual monitoring
  • Prevents unnecessary, disruptive restarts for problems that a restart would not actually resolve, by clearly separating liveness from readiness
  • Reduces the risk of sending real user login attempts to an instance that cannot correctly complete them
  • Gives operators clear, structured, machine-readable signals about the platform’s current condition, rather than relying purely on log inspection

Disadvantages & Trade-offs

  • Poorly configured checks — too strict, too lenient, or checking the wrong things — can cause more operational disruption than they prevent
  • Overly aggressive liveness checks risk triggering unnecessary restart loops during transient, self-resolving issues
  • Health check endpoints themselves must be secured thoughtfully, since they can reveal internal details about the server’s dependencies and condition
  • Requires ongoing tuning as a deployment’s own infrastructure and dependencies evolve, rather than being a purely one-time setup task

Why the tuning effort is worth it in production

For any Keycloak deployment supporting real user traffic, the cost of occasionally tuning probe timings and thresholds is small compared to the value of automatically and gracefully handling the kinds of transient issues — brief database hiccups, momentary network blips — that inevitably occur in any real production environment over time.

06

Defense

Security

Health check endpoints are often overlooked from a security standpoint precisely because their purpose feels purely operational, but they deserve real, deliberate attention.

Health endpoints can leak internal information

A health check response, particularly a detailed one listing individual contributing checks and their statuses, can reveal meaningful information about a system’s internal architecture and dependencies — for instance, confirming the presence and type of a specific database backend — information that would otherwise not be readily available to an external observer.

!
Common Misconception

It is easy to assume health check endpoints are harmless simply because they were designed for internal operational tooling rather than for end users. In reality, an unsecured, publicly reachable health endpoint can hand a would-be attacker a convenient, low-effort way to learn about a deployment’s internal dependencies and current operational state, information that can meaningfully assist in planning a more targeted attack.

Restricting network exposure

A common and sound practice is exposing Keycloak’s health endpoints only on an internal network path reachable by trusted infrastructure components — the orchestrator, the load balancer, internal monitoring — rather than making them reachable from the public internet alongside the regular login-facing endpoints.

Denial-of-service considerations

Because health endpoints are queried frequently and automatically, and because a readiness check often involves a real check against a backing dependency like a database, an attacker able to flood these specific endpoints with excessive requests could potentially place unnecessary additional load on that backing dependency, which is another reason to keep them appropriately access-restricted rather than openly exposed.

Health status as an operational signal, not a public status page

Health check endpoints are designed for automated infrastructure decision-making, not as a public-facing status page for end users. Deployments needing to communicate service status to external users or customers should build a separate, deliberately designed status communication mechanism, rather than exposing Keycloak’s own internal health endpoints directly for that purpose.

07

Visibility

Monitoring, Logging & Metrics

Health checks themselves are a form of monitoring, but they also deserve their own layer of monitoring — watching how often, and why, they fail over time.

Tracking probe failures over time, not just their current status

Rather than only reacting to the current pass-or-fail status of a probe at any given instant, mature operational practice involves tracking the history and frequency of probe failures over time, since a readiness check that fails only occasionally, for brief moments, tells a very different operational story than one that fails frequently or for extended periods.

Live
Current pass/fail status of the liveness endpoint
Ready
Current pass/fail status of the readiness endpoint
History
Frequency and duration of past probe failures over time

Correlating readiness failures with underlying dependencies

Because a readiness failure most commonly traces back to a specific underlying dependency — most often database connectivity — correlating readiness probe failures directly with monitoring data from that dependency itself helps operators quickly identify root causes, rather than treating a readiness failure as an isolated, unexplained event.

Watching for restart loops

An instance that is repeatedly failing liveness checks and being restarted in a tight, ongoing loop is a strong signal that either a genuine, deeper problem exists within that instance, or that the liveness check itself has been configured too strictly, triggering restarts for conditions that do not actually warrant one. Distinguishing between these two possibilities is an important part of correctly tuning a deployment’s health-check configuration over time.

Alerting thresholds appropriate to each probe type

Because a single readiness failure due to a brief, self-resolving issue is often expected and unremarkable, while a sustained readiness failure across an entire fleet of instances is a genuine incident, alerting thresholds should be calibrated specifically to distinguish between these very different situations, rather than treating every individual probe failure as equally significant.

08

Shape

Design Patterns & Anti-patterns

Teams running Keycloak in production at real scale tend to converge on a handful of well-tested patterns around how health checks are configured and consumed.

Pattern: Separate, conservative timing for liveness versus readiness

Mature deployments typically configure liveness checks with more conservative, forgiving thresholds — tolerating a few consecutive failures before triggering a restart — while allowing readiness checks to react somewhat more quickly, since the consequence of an incorrect readiness failure, briefly pausing traffic, is far less disruptive than an unnecessary restart triggered by an overly sensitive liveness check.

Pattern: Dedicated internal network path for health endpoints

Well-run deployments commonly expose health endpoints on a separate internal network interface or path, distinct from the public-facing login endpoints, ensuring that operational infrastructure can reach them reliably while keeping them out of reach of general internet traffic entirely.

Pattern: Startup probes tuned for clustering behavior

In clustered Keycloak deployments, where an instance may need meaningful time to join the cluster before being considered fully started, teams commonly tune startup probe thresholds specifically around observed real-world cluster-join timing, rather than relying on generic default values that may not reflect their particular deployment’s actual behavior.

Anti-pattern: Using one identical check for both liveness and readiness

A common and risky simplification is configuring the exact same check, with the exact same logic, for both liveness and readiness, rather than deliberately distinguishing between “should this be restarted” and “should this receive new traffic.” This conflates two genuinely different questions, and often leads to overly aggressive restarts for what should have been treated as a simple, temporary readiness issue instead.

ADR-118 · Health Probe Configuration Anti-pattern
Situation

A team, setting up Keycloak in a new Kubernetes environment quickly, configures both the liveness and readiness probes to point at the exact same aggregate health endpoint, including the database connectivity check, in order to simplify the initial setup.

Consequence

During a brief, routine database maintenance window, every Keycloak instance’s liveness check begins failing alongside readiness, triggering a wave of unnecessary restarts across the entire fleet at once, which then need to fully reinitialize and reconnect once the maintenance window ends, extending the actual user-facing disruption well beyond the original maintenance period itself.

Better Approach

Point liveness specifically at a narrow check confirming the core process itself is healthy, and reserve the broader, dependency-inclusive check for readiness alone, so a temporary, expected database maintenance window causes a brief, graceful pause in traffic rather than a disruptive, fleet-wide restart cycle.

09

Getting It Right

Best Practices & Common Mistakes

A handful of disciplined habits consistently separate a health-check configuration that quietly keeps a deployment resilient from one that becomes an unexpected source of outages.

Best Practice

Keep liveness narrow, readiness comprehensive

Liveness should confirm the process itself is healthy; readiness should confirm it can correctly serve requests right now.

Best Practice

Use a dedicated startup probe for slow-initializing deployments

Avoid mistaking a still-starting instance for a genuinely failed one, especially in clustered setups.

Best Practice

Restrict health endpoint exposure to trusted infrastructure

Keep these endpoints off the public internet, reachable only by the orchestrator, load balancer, and internal monitoring.

Best Practice

Tune probe timing against real observed behavior

Default threshold values are a starting point, not a guarantee of correctness for every specific deployment’s own characteristics.

Common Mistake

Treating liveness and readiness as interchangeable

Conflating the two leads directly to the kind of unnecessary, disruptive restart scenario described in the anti-pattern above.

Common Mistake

Never revisiting probe configuration after initial setup

A deployment’s real-world behavior often reveals that initial default thresholds need adjustment once genuine production traffic patterns emerge.

i
Practical Tip

When first configuring health checks for a new Keycloak deployment, deliberately simulate a temporary dependency failure — briefly disconnecting the database in a test environment, for example — and confirm that readiness fails gracefully while liveness remains stable, rather than assuming the configuration is correct simply because it looks reasonable on paper.

Health checks and readiness probes become most visible exactly in the kinds of production environments where Keycloak is expected to stay reliably available.

Kubernetes-orchestrated deployments

Organizations running Keycloak inside Kubernetes rely directly on its liveness, readiness, and startup probes to integrate with Kubernetes’ own native health-checking mechanisms, allowing Kubernetes to automatically restart genuinely failed instances and temporarily withhold traffic from instances that are merely experiencing a transient issue, without any manual operator intervention.

High-availability, multi-instance clusters

Deployments running several Keycloak instances behind a load balancer for high availability depend heavily on accurate readiness reporting to ensure traffic is only ever routed to instances genuinely capable of handling it correctly, which becomes especially important during rolling upgrades, where instances are being replaced one at a time while the overall service remains continuously available.

Kubernetes
Native integration through standard liveness/readiness probes
HA Clusters
Load balancers route only to genuinely ready instances
Rolling Upgrades
Readiness ensures traffic avoids instances mid-restart

Rolling upgrades and zero-downtime deployments

Organizations performing rolling upgrades of their Keycloak deployment rely on the startup and readiness probes together to ensure a newly deployed instance is only added back into active rotation once it has genuinely finished initializing and is confirmed capable of correctly handling requests, preventing users from experiencing failed login attempts during the upgrade process itself.

Managed and cloud-hosted Keycloak offerings

Providers offering managed Keycloak hosting build their own automated monitoring and remediation systems directly on top of these same health-check endpoints, using them as the foundational signal for decisions like automatic instance replacement or scaling, precisely because they provide a standardized, reliable way to assess an instance’s true operational condition.

11

Questions Answered

FAQ

Q1What is the practical difference between liveness and readiness for Keycloak?
Liveness answers whether the Keycloak process itself is fundamentally healthy or should be restarted. Readiness answers whether it is currently able to correctly handle new login requests, which can temporarily be “no” — for example, during a brief database outage — even while the process itself remains perfectly alive and does not need restarting.
Q2Why does Keycloak need a separate startup probe at all?
Because Keycloak, particularly in clustered configurations, can take meaningful time to fully initialize. A dedicated startup probe prevents an orchestrator from mistaking a still-initializing instance for a genuinely failed one, avoiding unnecessary restarts before the instance ever gets the chance to finish starting properly.
Q3Are Keycloak’s health check endpoints enabled by default?
Not necessarily in every configuration. The health check subsystem typically needs to be explicitly enabled as part of server configuration, alongside a deliberate decision about how broadly these endpoints should be network-exposed.
Q4Can a database outage cause Keycloak to be restarted unnecessarily?
It can, but only if liveness and readiness checks have been configured to check the exact same things. When properly separated, a database outage should cause readiness to fail — pausing traffic — while liveness remains healthy, avoiding an unnecessary restart that would not actually resolve a problem external to the Keycloak process itself.
Q5Should health check endpoints be publicly accessible?
Generally not. Because they can reveal internal details about a deployment’s dependencies and current state, and because they are intended for use by trusted infrastructure rather than end users, restricting their network exposure to internal, trusted systems is a widely recommended practice.
Q6How do health checks help during a rolling upgrade?
They ensure a newly deployed instance is only added back into active traffic rotation once its startup and readiness checks both confirm it has genuinely finished initializing and is capable of correctly handling requests, helping prevent users from experiencing failed logins against an instance that is still mid-restart.
12

Wrapping Up

Summary & Key Takeaways

Health Checks and Readiness Probes give the infrastructure surrounding Keycloak a precise, machine-readable vocabulary for a question that turns out to be far more nuanced than a simple “up or down” — is this specific instance fundamentally broken and in need of a restart, or is it merely, temporarily, not the right moment to send it new work? Getting this distinction right, and configuring liveness, readiness, and startup checks to reflect it accurately, is what allows a production Keycloak deployment to quietly absorb the small, inevitable bumps of real-world operation — a brief database hiccup, a slow cluster join — without those bumps turning into visible, disruptive outages for the people actually trying to log in.

Key Takeaways

  • Liveness, readiness, and startup answer three genuinely different questions — should this be restarted, can it serve traffic right now, and has it finished initializing.
  • Keycloak exposes these through a dedicated family of health endpoints — built on the underlying Quarkus and SmallRye Health framework.
  • Readiness checks real dependencies, like database connectivity — while liveness deliberately stays narrow, checking only the core process itself.
  • Conflating liveness and readiness is a common, costly mistake — it turns temporary, self-resolving issues into unnecessary, disruptive restarts.
  • Health endpoints should be treated as sensitive infrastructure — restricted to trusted internal networks rather than exposed publicly.
  • Startup probes matter especially for clustered deployments — preventing a still-initializing instance from being mistaken for a failed one.
  • Good probe configuration is tuned, not assumed — deliberately testing failure scenarios reveals whether the setup behaves as intended before a real incident does.