Page MenuHomeVyOS Platform

dhcp: dhclient unicast RENEW to a dead server can stick until lease end
In progress, NormalPublicBUG

Description

Summary

ISC dhclient can remain in unicast RENEW toward a DHCP server that has lost
the client session for the remainder of the lease lifetime (often many hours),
while the WAN link stays administratively and carrier UP. The interface may
still hold a previously assigned address; no DISCOVER / INIT-REBOOT is
attempted until expire.

This is distinct from T9085 (RENEW succeeds but does not reinstall a missing
kernel default). Here RENEW never successfully completes against a live server.

Why it matters

  1. Multi-WAN / HA: a primary path can look "configured" (address present, dhclient running) while it cannot extend the lease or recover after ISP session loss. Failover tools that key only on "default route present" may not demote; tools that probe the path see permanent loss until expire or manual dhclient restart.
  1. Production (VyOS 1.5 rolling, 2026-07-11..13): Comcast DHCPv4 on a dual-stack WAN stayed broken ~10.5 hours with IPv6 still healthy on the same interface. Root cause class: wedged unicast-RENEW; recovery was restarting dhclient@iface.
  1. RFC 2131 allows waiting until T2 (REBIND) / expire; product expectation on a router is earlier recovery when the server never answers RENEW.

Reproduction (conceptual)

  1. BOUND on ethN with a multi-hour lease (T1 = renew time well before expire).
  2. Cause the DHCP server to drop the session without taking the link down (ISP modem session reset, server reboot that forgets leases, etc.).
  3. Observe dhclient continue unicast RENEW without rewriting the ISC lease "renew" timestamp into the future.
  4. Without intervention, no rediscovery until expire.

Suggested fix

Preferred (implemented in accompanying PR):

  • Periodic watchdog: for each active dhclient@<iface>, parse the last record in /run/dhclient/dhclient_<iface>.leases.
  • If "renew" is more than GRACE (e.g. 15m) in the past and "expire" is still in the future, systemctl restart dhclient@<iface> (cooldown e.g. 30m).
  • Force INIT / INIT-REBOOT path instead of sitting on a dead unicast target.

Alternatives:

  • Patch isc-dhclient to cap failed RENEW attempts then reboot state (heavier, Debian packaging).
  • Document operator revive only (insufficient for unattended edges).

Environment

  • VyOS 1.5 Circinus rolling
  • DHCP WANs with multi-hour ISP leases
  • Dual-stack interfaces where v4 can wedge independently of v6

Workaround

External health daemon restarts dhclient@ after prolonged path failure
(wan-failover revive_cmd, 15m + repeat). Does not help if path probes still
pass but lease cannot renew (rarer).

Related

  • T9085 — RENEW success without reinstalling missing default (exit-hook PR)
  • Do not merge the two issues: different code paths and fixes

Details

Version
VyOS Rolling (1.5 / Circinus)
Is it a breaking change?
Unspecified (possibly destroys the router)
Issue type
Bug (incorrect behavior)

Event Timeline

Viacheslav changed the task status from Open to In progress.Jul 27 2026, 12:01 PM
Viacheslav assigned this task to bradkollmyer.
Viacheslav triaged this task as Normal priority.
Viacheslav subscribed.

Addressed review on https://github.com/vyos/vyos-1x/pull/5341 (e1d43131f):

debian/rules already copies src/helpers/* into usr/libexec/vyos, but debian/vyos-1x.install only listed *.py and *.sh. The extensionless watchdog was dropped from the package while the systemd unit and timer were installed, so the timer hit ENOENT on a built image (Copilot packaging note; alexk37 confirmed on-box). Added an explicit usr/libexec/vyos/vyos-dhclient-lease-watch install line.

Also dropped iface.endswith('v6') from the watcher: VyOS IPv6 DHCP is dhcp6c@<iface>, not a dhclient_*v6.conf file.