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.