This document describes the correct and supported networking models for running Incus on hosts with a routed public IPv4 /32, such as Hetzner ARM and similar cloud servers. It also documents common pitfalls, misleading error messages, and the rationale behind the recommended setup.
1. Host Characteristics
Typical properties of these systems:
- Public IPv4 address with
/32netmask - Provider-managed gateway (not on-link)
- No traditional LAN
- nftables-based firewall
- systemd-networkd or provider networking
These hosts are not LAN environments. Any tooling that assumes broadcast, ARP-based gateways, or DHCP on the host will fail or behave unpredictably.
2. What Incus Does Not Depend On
Incus does not depend on:
lxc-net- system-wide
dnsmasq lxcbr0- legacy LXC bridge tooling
Incus uses the LXC runtime (liblxc) but provides its own networking stack. Installing lxc-net introduces a second, incompatible network manager and must be avoided.
3. Why Incus NAT Bridges Fail on Routed /32 Hosts
When attempting to create a NAT bridge such as incusbr0, Incus may fail with errors like:
dnsmasq: failed to create listening socket for 10.x.x.1: Address already in use
Important clarification:
- This error is not caused by a running
dnsmasqprocess - It persists even when
dnsmasqis removed or masked - It occurs with any RFC1918 subnet
Root Cause
On routed /32 hosts, the kernel networking policy rejects assigning private RFC1918 gateway addresses to new interfaces. Incus reports the failure at the dnsmasq stage, but the actual failure occurs earlier at the kernel address assignment level.
This is a hard architectural constraint of the host environment.
4. Forbidden Configurations
The following configurations must never be used on Incus hosts:
- Enabling
lxc-net.service - Creating
lxcbr0 - Running system-wide
dnsmasq - NAT bridges with DHCP (
incusbr0+ dnsmasq) - Mixing Incus and legacy LXC networking
These setups cause address conflicts, misleading error messages, and non-deterministic behavior.
5. Supported Networking Models
5.1 Routed IPv4 (Recommended if Extra IPs Exist)
This is the preferred model on routed hosts.
Requirements
- At least one additional routed IPv4 address from the provider
Configuration
Attach a routed NIC directly to the container:
incus config device add <container> eth0 nic \
nictype=routed \
parent=eth0 \
ipv4.address=<public-ip>
Notes:
- No bridge is created
- No DHCP is involved
- No dnsmasq is used
- The container receives the public IP directly
The container will auto-configure the address and routing.
5.2 Routed IPv6 (Cleanest Long-Term Solution)
If the provider offers IPv6:
incus config device add <container> eth0 nic \
nictype=routed \
parent=eth0 \
ipv6.address=<ipv6-address>
This avoids IPv4 NAT entirely and aligns with modern network design.
5.3 Proxy Devices (When No Extra IPs Exist)
If no additional IPs are available:
- Keep the container isolated
- Expose services via Incus proxy devices
Example:
incus config device add <container> web proxy \
listen=tcp:0.0.0.0:443 \
connect=tcp:127.0.0.1:443
This avoids container-level networking entirely.
6. Why Static NAT Bridges Are Not an Option Here
While Incus supports bridges without DHCP, routed /32 hosts typically still reject RFC1918 gateway assignment. Even with:
ipv4.dhcp=false- no dnsmasq installed
The kernel-level restriction remains.
Conclusion:
NAT bridges are fundamentally incompatible with routed /32 host networking.
7. Operational Recommendations
- Do not install
lxcunless raw LXC is required - Mask
lxc-net.servicepermanently - Avoid LAN assumptions on server hosts
- Prefer routed NICs or proxy devices
- Treat container names and IPs as stable infrastructure APIs
8. Summary
- Incus itself is not at fault; failures are caused by host networking constraints or conflicts.
- On routed
/32hosts, NAT bridges are often impossible due to kernel routing policy. - Legacy LXC networking (
lxc-net) and system-widednsmasqmust not be mixed with Incus. - Use routed NICs, IPv6, or proxy devices for deterministic results.
Appendix A: BIND / FireHOL Variant (LAN-style Hosts)
On some hosts that do provide a LAN-style environment (non-/32), Incus bridge creation may fail for a different reason: port 53 conflicts and firewall policy.
Symptoms
dnsmasq: failed to create listening socket for <bridge-ip>: Address already in use
Typical Causes
- A system DNS service (e.g. BIND /
named) already listening on port 53 - Firewall policies (e.g. FireHOL) blocking bridge or NAT traffic
Resolution Strategy
- Create the Incus bridge without DHCP/DNS (avoid
dnsmasqentirely):
incus network create incusbr0 \
ipv4.address=192.168.100.1/24 \
ipv4.nat=true \
ipv4.dhcp=false \
ipv6.address=none
- Allow bridge traffic in FireHOL (example):
# Incus bridge
interface4 incusbr0 br
server all accept
client all accept
router br_to_host inface incusbr0 outface any
server all accept
route all accept
Reload firewall rules:
firehol restart
- Attach the network to the default profile:
incus profile device add default eth0 nic network=incusbr0 name=eth0
- Configure a static IP inside the container (Debian 13, systemd-networkd):
# /etc/systemd/network/10-eth0.network
[Match]
Name=eth0
[Network]
Address=192.168.100.10/24
Gateway=192.168.100.1
DNS=8.8.8.8
Enable networking:
systemctl enable systemd-networkd
systemctl restart systemd-networkd
Notes
- This appendix applies only to LAN-style hosts where RFC1918 gateways are permitted.
- On routed
/32hosts (Hetzner-style), this model is not supported; use routed NICs instead.
- Incus is functioning correctly
- The host environment is restrictive by design
- Legacy LXC networking must not be mixed with Incus
- Routed NICs are the correct solution
This setup is deterministic, production-grade, and aligned with how Incus is designed to run on modern cloud servers.
- Log in to post comments