Reported symptoms
A hypervisor host dies at 03:20. The order-entry VM rbdr-vm-orders is restored
to the recovery cluster at the second site and reaches a login prompt at 04:01.
The guest then reports healthy in every way it can: the boot completes, the order service binds 8443, the guest agent answers the platform, and the interface is up with a carrier. Nothing reaches it. The load balancer marks the pool member down, and the guest reaches neither its database, nor its directory, nor its own default gateway, for which its ARP table holds no entry.
The call spends fifty minutes on storage, because a machine that answers on the console and reaches nothing feels like a damaged image. The quarterly restore test for this VM has recorded PASS six quarters running, into this same cluster.
Evidence provided
First, the definitions. Production export and restored configuration name the
same bridge, vmbr1, and the same tag, 41, and the MAC is unchanged — which
removes the interface rename and the missed DHCP reservation.
$ grep -E '^net[0-9]+:' /etc/pve/qemu-server/8121.confSecond, the guest’s address configuration: the static 10.20.41.24/24 it has
always held, default route via 10.20.41.1, no DHCP client, no lease file, no
IPAM record of this address.
Third, the layer-two probe, the test that does not depend on the guest: a helper
VM on vmbr1 with tag 41 on the same recovery host, statically addressed in
10.20.41.0/24.
$ arping -c 3 -I eth0 10.20.41.24; ip -d link show vmbr1; bridge vlan show dev vmbr1Helper and guest exchange ARP and ICMP; neither reaches anything beyond the recovery host on that segment. And the two bridges sharing the name are not the same thing: on the recovery host, a single uplink to a switch port carrying one untagged segment; on the production host, a bond to a trunk carrying VLANs 40 to 49.
Fourth, the control: a three-step procedure — restore, power on, confirm a login prompt on the hypervisor console — recording its result on the third. It names no client, no dependency, no transaction.
Work the evidence before reading on
- The helper on the same bridge and tag reaches the guest; nothing beyond the host does. Which attachment fault does that confirm, and which does it rule out?
- The guest holds a static address and runs no DHCP client. What family of explanations does that remove?
- The guest booted, mounted its filesystems and bound its port. What does that establish about the disk image, and what does it not?
- The restore test passed six times here. What did each pass actually assert?
Root cause
The segment was not carried at the recovery target
The definition asked for vmbr1, tag 41. The recovery host has a bridge called
vmbr1, so the name matched, the restore reported nothing, and the interface
was attached exactly as instructed — to a bridge whose uplink does not trunk 41.
Every reading inside the guest was accurate and useless. The virtual link terminates at the bridge, so the carrier was genuine and the address right for the segment the machine belongs on; the frames crossed the bridge and were discarded above the host.
The probe separates the two faults in this signature without the guest’s cooperation. A helper on the same bridge and tag that cannot reach the guest means the interface sits on a different bridge from the one configured. A helper that can reach it, while nothing beyond the host can, means the attachment is sound and the fault is above it — the tag not carried, or the uplink not trunking it. That is this incident.
The restore test asserted that the guest booted
Reaching a login prompt on the hypervisor console is the whole of what the quarterly test asserted, and it was true on all six occasions.
Resolution
Do not re-run the restore. Read the attachment on both sides first, since the repair differs by which fault the probe identified.
set -u
VMID=8121
BRIDGE=vmbr1
grep -E '^net[0-9]+:' "/etc/pve/qemu-server/${VMID}.conf"
ip -d link show "$BRIDGE"
bridge vlan show dev "$BRIDGE"
Then repair the segment rather than the setting. Making the recovery host’s uplink carry VLAN 41 fixes this VM and every future restore onto that segment; moving the interface to a bridge that already trunks 41 fixes this VM and leaves the next restore to rediscover the fault. Prefer the first; take the second only as a temporary measure inside the outage.
The guest needs no change. Its address, route and MAC were correct throughout, and any edit made to them during the incident is a second fault to unwind.
Verification
Verification originates where the callers originate, because the hypervisor console can report success while the incident continues.
set -u
VM_IP=10.20.41.24
VM_FQDN=rbdr-orders.example.internal
PROBE=rbdr-client-probe.example.internal
ssh "$PROBE" "ping -c 3 -W 2 $VM_IP"
ssh "$PROBE" "curl -fsS https://$VM_FQDN/healthz"
ssh "$PROBE" "curl -fsS -X POST https://$VM_FQDN/rbdr-selftest/order"
Establish in order: a machine on the client subnet exchanges traffic with the guest; the guest reaches its database and directory; the certificate offered on the client-facing port is valid for the name clients use; and a transaction a user would recognise completes and survives a restart.
Then verify the control. Re-run the rewritten quarterly test against a cluster with the uplink change reverted and confirm it now fails. A control that cannot fail on the defect it exists to catch has not been fixed.
Prevention
Test the segment, not the bridge name. Matching names are what let this restore report success. Record per VM the bridge, the tag and the uplink that carries it at both sites, and treat a name resolving to a different segment as a defect.
End every restore test with a completed transaction, issued from the client subnet. A login prompt is the first stage of a validation, not its result.
Keep a layer-two probe in the recovery site. Attaching it to any bridge and tag answers the wrong-bridge question without the guest’s cooperation.
Diff the recovery site against production on network attachment. Readiness reviews count CPU, memory and storage. Which VLANs an uplink trunks decided this incident, and no capacity review has a column for it.