Tags

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 /32 netmask
  • 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 dnsmasq process
  • It persists even when dnsmasq is 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 lxc unless raw LXC is required
  • Mask lxc-net.service permanently
  • 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 /32 hosts, NAT bridges are often impossible due to kernel routing policy.
  • Legacy LXC networking (lxc-net) and system-wide dnsmasq must 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

  1. Create the Incus bridge without DHCP/DNS (avoid dnsmasq entirely):
incus network create incusbr0 \
  ipv4.address=192.168.100.1/24 \
  ipv4.nat=true \
  ipv4.dhcp=false \
  ipv6.address=none
  1. 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
  1. Attach the network to the default profile:
incus profile device add default eth0 nic network=incusbr0 name=eth0
  1. 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 /32 hosts (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.