Daniel has it. I hit exactly this on a pumping station Pi last year. Two things are configuring eth0: dhcpcd starts at boot, finds no DHCP server and gives the port a 169.254 link-local address plus routes, and then ifup tries to add its own address and default route. The route is already there, so the kernel answers “File exists” and ifup gives up. Depending on which one wins the race at boot, your gateway gets out or not.
Pick one. On Bullseye that means dhcpcd. Remove the eth0 block from /etc/network/interfaces (leave the file with only the source line) and put the static setup in /etc/dhcpcd.conf:
interface eth0
static ip_address=10.40.2.20/24
static routers=10.40.2.1
static domain_name_servers=10.40.2.1
noipv4ll
Then clean up without a reboot:
sudo ip addr flush dev eth0
sudo systemctl restart dhcpcd
ip addr show eth0
noipv4ll stops the 169.254 address. If you move to Bookworm later, dhcpcd is gone and you do the same with nmcli, so keep a note of that.

