Control Plane Reporting Status shows Data Planes that are no longer active

Uses: Kong Gateway
TL;DR

Why does /clustering/data-planes still show sync_status: normal for a Data Plane that’s been turned off?

sync_status is written by the Data Plane the last time it successfully reported in, and isn’t re-evaluated based on current reachability — a Data Plane that’s gone silent just keeps showing its last reported status. Check the last_seen timestamp instead to gauge freshness; an unreachable Data Plane keeps proxying with its last-known config until cluster_data_plane_purge_delay (default 14 days) removes its entry.

Problem

When querying /clustering/data-planes on the Control Plane’s Admin API, every Data Plane shows "sync_status":"normal" even when a given Data Plane has been turned off.

Cause

The last_seen field on each data_plane entry can be used to determine the “freshness” of the data_plane information — sync_status itself is written by the Data Plane the last time it successfully reported to the Control Plane, and is not re-evaluated or flipped based on whether that Data Plane is still reachable. A Data Plane that has gone silent simply keeps showing whatever sync_status it last reported, alongside a last_seen timestamp that stops advancing.

If a data_plane stops reporting to the control plane it is still perfectly capable of continuing to proxy using its last good received configuration. A data_plane that does not report in will eventually be purged from the database table according to the configuration cluster_data_plane_purge_delay, which defaults to 14 days (1209600 seconds) on Kong Gateway 3.14.0.0.

The data_planes are designed to be resilient to loss of connection to the control_plane. The fact that a data_plane has not communicated with the control plane is not necessarily a problem.

Solution

To get just the data_planes heard from within the last hour:


curl -s "http://localhost:8001/clustering/data-planes" -H "Kong-Admin-Token: password" | jq ".data[] | select(.last_seen > (now | floor) - 3600)"

which, on a current 3.14.0.0 Control Plane, returns an entry shaped like this (some fields — cert_details, rpc_capabilities, labels — did not exist in older Kong versions and have been added since):


{
  "id": "520857cb-b5ee-4833-95e2-c02f4d500104",
  "hostname": "e000a45a39fc",
  "ip": "172.18.0.5",
  "version": "3.14.0.0",
  "last_seen": 1787814396,
  "updated_at": 1787814396,
  "ttl": 1209586,
  "config_hash": "4b5b286e7267a66d2b4fed6970847502",
  "sync_status": "normal",
  "labels": {},
  "rpc_capabilities": [],
  "cert_details": {
    "expiry_timestamp": 1827377031
  }
}

Note: the version field inside the JSON body reports a plain version string (e.g. "3.14.0.0") with no -enterprise-edition suffix — that suffix only appears in HTTP Server/Via headers and kong version CLI output, never inside a JSON response body.

Or flip the comparison to find data_planes that are missing for more than an hour.

Alternatively, cluster_data_plane_purge_delay can be lowered, for example to 1 hour, so that unavailable DPs are not kept in the report for as long, providing a more up-to-date view of which DPs are actually connected.

As a demonstration, using docker-compose the following can be set to a very low value, e.g. 10 seconds, on the Control Plane’s config:


KONG_CLUSTER_DATA_PLANE_PURGE_DELAY: 10

With that set, stopping a Data Plane’s container will show its entry continuing to appear in /clustering/data-planes — with an unchanging last_seen, a sync_status frozen at whatever it last reported (commonly "normal"), and a ttl counting down — for up to 10 seconds after the container stops, after which the entry disappears from data: [] entirely. Starting the container again causes it to reappear (with a new id and a fresh last_seen) the next time it successfully syncs with the Control Plane.

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!