Fixing USB Gadget Networking on a Pi Zero 2W (When cloud-init Keeps Undoing Your Config)
I set up a Raspberry Pi Zero 2W as a small USB gadget device — plug it into a laptop, get a network interface, SSH in. Simple in theory. In practice, every reboot quietly erased my network config, and it took a while to figure out why.
The symptom
I’d configure usb0 with a static IP, reboot to confirm it stuck, and find it gone. Not broken — gone, reset back to whatever the image shipped with. No errors, no obvious culprit in the logs I was looking at first. Just a config that refused to stay changed.
The actual cause
It wasn’t the USB gadget setup at all. It was cloud-init. On every boot, cloud-init was regenerating the network configuration and stomping on whatever I’d set manually in /etc/network/interfaces.d/. This is a common gotcha on Raspberry Pi OS images that ship with cloud-init enabled for provisioning — it’s designed to enforce a known network state on boot, which is exactly what you don’t want once you’re hand-configuring an interface.
The fix
Two steps. First, tell cloud-init to stop managing networking entirely:
sudo bash -c 'echo "network: {config: disabled}" > /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg'
Second, set up usb0 manually in /etc/network/interfaces.d/50-cloud-init with a static IP:
auto usb0
iface usb0 inet static
address 192.168.2.2
netmask 255.255.255.0
gateway 192.168.2.1
I also removed the IPv6 DHCP line that was in there by default — one less thing trying to auto-negotiate a state I didn’t want.
Bringing up the host side
On the Mac side, the Pi has to come up first, then you bring up the corresponding interface:
sudo ifconfig en8 192.168.2.1 netmask 255.255.255.0
(Your interface name will vary — check ifconfig for whatever shows up when you plug the Pi in.)
Once both sides are up:
ssh pi@192.168.2.2
And it just connects.
The lesson
If a Pi’s network config keeps reverting after reboot and nothing in your own setup explains it, check for cloud-init before you assume you’ve misconfigured something. It’s easy to spend an hour debugging dhcpcd or NetworkManager when the real culprit is a provisioning tool quietly doing its job — just not the job you wanted.