Skip to content

Instantly share code, notes, and snippets.

@nfl0
Last active May 15, 2026 23:37
Show Gist options
  • Select an option

  • Save nfl0/189222c24b61c75f4aa23e67490ff54b to your computer and use it in GitHub Desktop.

Select an option

Save nfl0/189222c24b61c75f4aa23e67490ff54b to your computer and use it in GitHub Desktop.
Fix for Intel I219-LM "e1000e Detected Hardware Unit Hang" — NIC randomly drops link on Linux/Proxmox until power-cycle. Idempotent, reboot-persistent script that disables the offload + EEE/LPI triggers.
#!/usr/bin/env bash
#
# Intel I219-LM / e1000e "Detected Hardware Unit Hang" mitigation.
#
# Symptom: NIC TX engine hangs after hours/days of uptime, link drops,
# only a physical power-cycle recovers it (warm reboot does not).
# Cause: I219 silicon errata exercised by (a) hardware offloads and
# (b) EEE/LPI low-power-idle transitions. We disable BOTH triggers.
#
# Run as root after a fresh Proxmox install. Idempotent + reboot-persistent
# via a systemd oneshot (interface-name independent, survives renames).
#
set -euo pipefail
ETHTOOL=/usr/sbin/ethtool
OFFLOADS="gso off gro off tso off tx off rx off sg off rxvlan off txvlan off"
UNIT=/etc/systemd/system/e1000e-no-offload.service
[[ $EUID -eq 0 ]] || { echo "Run as root." >&2; exit 1; }
command -v "$ETHTOOL" >/dev/null || { apt-get update -qq && apt-get install -y ethtool; }
# Find every NIC bound to the e1000e driver.
mapfile -t NICS < <(
for d in /sys/class/net/*; do
[[ -e "$d/device/driver" ]] || continue
[[ "$(basename "$(readlink -f "$d/device/driver")")" == e1000e ]] && basename "$d"
done
)
[[ ${#NICS[@]} -gt 0 ]] || { echo "No e1000e NIC found — nothing to do."; exit 0; }
echo "e1000e NIC(s): ${NICS[*]}"
# 1. Apply now (safe, no link drop).
for n in "${NICS[@]}"; do
echo "Disabling offloads + EEE on $n ..."
$ETHTOOL -K "$n" $OFFLOADS || true
$ETHTOOL --set-eee "$n" eee off || true
done
# 2. Persist across reboots, independent of /etc/network/interfaces layout.
cat > "$UNIT" <<EOF
[Unit]
Description=Disable e1000e hardware offloads (I219 hang workaround)
Wants=network-pre.target
Before=network-pre.target
DefaultDependencies=no
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c 'for d in /sys/class/net/*; do [ -e "\$d/device/driver" ] || continue; [ "\$(basename \$(readlink -f \$d/device/driver))" = e1000e ] || continue; n=\$(basename \$d); $ETHTOOL -K \$n $OFFLOADS || true; $ETHTOOL --set-eee \$n eee off || true; done'
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now e1000e-no-offload.service >/dev/null 2>&1 || systemctl enable e1000e-no-offload.service
# 3. Verify.
echo "--- verification ---"
for n in "${NICS[@]}"; do
echo "[$n]"
$ETHTOOL -k "$n" | grep -E '^(tx-checksumming|rx-checksumming|scatter-gather|tcp-segmentation-offload|generic-segmentation-offload|generic-receive-offload):'
$ETHTOOL --show-eee "$n" 2>/dev/null | grep -E 'EEE status:' || true
done
echo "Done. Persistent via $UNIT"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment