Summary
Deleting an HTTPProxy leaves its anchor behind on the Karmada hub, and everything the anchor owns stays alive and serving with it.
The anchor is the only thing tying a derived Gateway and HTTPRoute to an upstream object that lives on a different control plane, so nothing else can collect them. Each surviving Gateway then mints a Let's Encrypt Issuer, and one edge cluster has reached 902 Issuers driving 42 requests per second against a fleet baseline of 0.13.
One project namespace on the hub holds 145 anchors today, the oldest from 16 July.
Acceptance criteria
What is happening
Read on the Karmada hub on 2026-09-17 at 01:20Z, in ns-45e239ee-7a69-4e44-ba30-48f73f431101, project integration-24be19.
The hub still holds e2e-path-routing-2026-08-01t08-46-39z as both an HTTPRoute and a Gateway, created 1 August, with live ResourceBindings. The project control plane holds nothing from that date, so the upstream HTTPProxy is long gone.
The route carries a single ownerReference to a ConfigMap named anchor-f99c6b9b-907c-4e85-b1d5-d53544c95448, also created 1 August and still present. It carries no data. Its labels name what it stands for: meta.datumapis.com/upstream-cluster-name, upstream-group, upstream-kind, upstream-name and upstream-namespace.
Karmada is behaving correctly throughout. It propagates objects that genuinely exist, so the edge copies are right. The whole cascade is one delete away and that delete never happens.
Why nothing collects it
GatewayDownstreamGCReconciler deletes the anchor, but only for an object it observes going through a finalized deletion:
if dt := obj.GetDeletionTimestamp(); dt.IsZero() || !controllerutil.ContainsFinalizer(&obj, gatewayControllerGCFinalizer) {
return ctrl.Result{}, nil
}
Miss that window, whether the controller is down, the finalizer is absent, or the event is dropped, and nothing revisits it. The reconciler is keyed on an upstream object that no longer exists, and the anchor carries no owner of its own, so Kubernetes garbage collection has nothing to follow either.
That is the same shape as #233, which proposed a periodic scan over owned resources and was closed in favour of one-off cleanups.
What a responder sees
Ten HTTPRouteStatusWarning alerts are firing in production against two of these routes across five sites, which is how this was found. They are accurate: the backendRef Services really are absent. The objects are broken and they are also immortal.
Related: #182 is the same failure on ResourceClaims, where deleting an HTTPProxy leaves quota consumed. https://github.com/datum-cloud/infra/issues/4684 records the Issuer and rate-limit cost.
Summary
Deleting an HTTPProxy leaves its anchor behind on the Karmada hub, and everything the anchor owns stays alive and serving with it.
The anchor is the only thing tying a derived Gateway and HTTPRoute to an upstream object that lives on a different control plane, so nothing else can collect them. Each surviving Gateway then mints a Let's Encrypt Issuer, and one edge cluster has reached 902 Issuers driving 42 requests per second against a fleet baseline of 0.13.
One project namespace on the hub holds 145 anchors today, the oldest from 16 July.
Acceptance criteria
What is happening
Read on the Karmada hub on 2026-09-17 at 01:20Z, in
ns-45e239ee-7a69-4e44-ba30-48f73f431101, projectintegration-24be19.The hub still holds
e2e-path-routing-2026-08-01t08-46-39zas both an HTTPRoute and a Gateway, created 1 August, with live ResourceBindings. The project control plane holds nothing from that date, so the upstream HTTPProxy is long gone.The route carries a single
ownerReferenceto a ConfigMap namedanchor-f99c6b9b-907c-4e85-b1d5-d53544c95448, also created 1 August and still present. It carries no data. Its labels name what it stands for:meta.datumapis.com/upstream-cluster-name,upstream-group,upstream-kind,upstream-nameandupstream-namespace.Karmada is behaving correctly throughout. It propagates objects that genuinely exist, so the edge copies are right. The whole cascade is one delete away and that delete never happens.
Why nothing collects it
GatewayDownstreamGCReconcilerdeletes the anchor, but only for an object it observes going through a finalized deletion:Miss that window, whether the controller is down, the finalizer is absent, or the event is dropped, and nothing revisits it. The reconciler is keyed on an upstream object that no longer exists, and the anchor carries no owner of its own, so Kubernetes garbage collection has nothing to follow either.
That is the same shape as #233, which proposed a periodic scan over owned resources and was closed in favour of one-off cleanups.
What a responder sees
Ten
HTTPRouteStatusWarningalerts are firing in production against two of these routes across five sites, which is how this was found. They are accurate: thebackendRefServices really are absent. The objects are broken and they are also immortal.Related: #182 is the same failure on ResourceClaims, where deleting an HTTPProxy leaves quota consumed. https://github.com/datum-cloud/infra/issues/4684 records the Issuer and rate-limit cost.