Netplan Multiple Default Routes: Ubuntu Policy Routing Guide 2026

How to Fix Netplan Multiple Default Routes on Ubuntu: Policy Routing, Metrics and Two-NIC Servers

Configuring two network interfaces on Ubuntu is easy—until both interfaces need their own gateway.

A typical server may have one interface connected to a public or management network and another connected to a private, storage, backup, or application network. Everything can look correct at first: both interfaces are up, both IP addresses respond to ping, and Netplan accepts the YAML configuration.

Then the strange behavior begins.

SSH works through one address but not the other. Connections arrive through one interface and replies leave through another. Internet access works only intermittently. A route appears correct but Linux still chooses an unexpected interface. In other cases, Netplan warns about conflicting default routes.

These problems are usually not random. They result from the interaction between default routes, route metrics, Linux routing tables, source addresses and policy routing.

This guide explains how to configure and troubleshoot multiple default routes on Ubuntu using Netplan, including practical two-NIC configurations, route metrics, custom routing tables and source-based policy routing.


SEO Information

Meta Title: Netplan Multiple Default Routes: Ubuntu Policy Routing Guide

Meta Description: Fix Netplan multiple default routes on Ubuntu using route metrics, policy routing, custom routing tables and reliable two-NIC configurations.

Focus Keyword: Netplan multiple default routes

Secondary Keywords: Ubuntu multiple default gateways, Netplan policy routing, Ubuntu two NICs, Linux multiple default routes, Netplan route metric, source based routing Ubuntu, Netplan routing-policy

Recommended Slug: netplan-multiple-default-routes-policy-routing

Category: Networking

Search Intent: Troubleshooting / How-to / Configuration


Table of Contents

  1. Why Multiple Default Routes Cause Problems
  2. Inspect the Existing Network
  3. How Linux Selects a Route
  4. Route Metrics Explained
  5. Primary and Backup Gateway Configuration
  6. When Metrics Are Not Enough
  7. Source-Based Policy Routing
  8. Complete Netplan Two-NIC Configuration
  9. Apply Netplan Safely
  10. Verify Routing
  11. Troubleshoot Wrong-Interface Traffic
  12. DHCP and Cloud Networking Problems
  13. Common Mistakes
  14. FAQ

Why Do Multiple Default Routes Cause Problems?

Suppose an Ubuntu server has two interfaces:

enp1s0
IP:      192.168.10.10/24
Gateway: 192.168.10.1

enp2s0
IP:      10.20.30.10/24
Gateway: 10.20.30.1

Both networks provide a route beyond their local subnet.

The server could therefore end up with:

default via 192.168.10.1 dev enp1s0
default via 10.20.30.1 dev enp2s0

But a default route means:

Use this route when no more specific route matches the destination.

When two default routes coexist, Linux needs a predictable method for determining which route should handle a particular packet.

Understanding this behavior is much easier if you already understand IP addressing, gateways and routing. CorgiNetwork’s <a href=”https://corginetwork.com/computer-networking-explained/“>Computer Networking Explained</a> provides a broader networking foundation, while the <a href=”https://corginetwork.com/tcp-ip-explained-a-complete-guide-to-tcp-ip-model/“>TCP/IP Explained guide</a> explains how IP routing fits into the TCP/IP architecture.

For authoritative Netplan syntax and routing properties, keep the <a href=”https://netplan.readthedocs.io/en/stable/netplan-yaml/” target=”_blank” rel=”noopener”>official Netplan YAML reference</a> available while working through the configuration.


Inspect the Existing Ubuntu Network First

Never begin by copying a Netplan configuration from the Internet.

First determine what the server currently has.

Run:

ip -br addr

Example:

lo       UNKNOWN  127.0.0.1/8
enp1s0   UP       192.168.10.10/24
enp2s0   UP       10.20.30.10/24

Then inspect the current routing table:

ip route

You might find:

default via 192.168.10.1 dev enp1s0
default via 10.20.30.1 dev enp2s0

192.168.10.0/24 dev enp1s0 proto kernel scope link src 192.168.10.10
10.20.30.0/24 dev enp2s0 proto kernel scope link src 10.20.30.10

Now inspect policy-routing rules:

ip rule

Finally, check Netplan itself:

sudo netplan get

and:

ls -la /etc/netplan/

If you want a broader reference for commands such as ip, ss, ping, dig, traceroute and tcpdump, see CorgiNetwork’s <a href=”https://corginetwork.com/linux-network-tools-guide/“>Linux Network Tools Guide</a>.

The important principle is simple:

Do not change routing until you understand who currently controls it.

Possible sources include Netplan, NetworkManager, systemd-networkd, DHCP, cloud-init, VPN software and cloud networking agents.


How Linux Selects a Route

Linux does not simply choose a gateway at random.

Routing decisions involve several factors, including:

  • destination address;
  • routing table;
  • route prefix;
  • metric;
  • policy-routing rules;
  • source address;
  • interface state.

A highly useful diagnostic command is:

ip route get 8.8.8.8

Instead of printing the entire routing table, this asks the kernel:

Which route would you actually use to reach this destination?

For example:

8.8.8.8 via 192.168.10.1 dev enp1s0 src 192.168.10.10

This tells you the selected:

  • gateway;
  • interface;
  • source IP.

For policy-routing configurations, you can go further:

ip route get 8.8.8.8 from 192.168.10.10

and:

ip route get 8.8.8.8 from 10.20.30.10

This becomes extremely useful later.


Understanding Route Metrics

Suppose the first interface should be the normal Internet connection while the second should have a less-preferred default route.

You can assign different metrics.

For example:

default via 192.168.10.1 metric 100
default via 10.20.30.1 metric 200

For otherwise competing routes, the lower metric generally has higher preference.

This concept is documented in Canonical’s <a href=”https://documentation.ubuntu.com/server/explanation/networking/configuring-networks/” target=”_blank” rel=”noopener”>Ubuntu Server networking documentation</a>, while Netplan exposes route metrics through its route configuration.


Primary and Secondary Gateway with Netplan

A practical configuration might be:

network:
  version: 2
  renderer: networkd

  ethernets:

    enp1s0:
      addresses:
        - 192.168.10.10/24

      routes:
        - to: default
          via: 192.168.10.1
          metric: 100

      nameservers:
        addresses:
          - 1.1.1.1
          - 8.8.8.8


    enp2s0:
      addresses:
        - 10.20.30.10/24

      routes:
        - to: default
          via: 10.20.30.1
          metric: 200

After applying the configuration, Linux should have routes conceptually similar to:

default via 192.168.10.1 dev enp1s0 metric 100
default via 10.20.30.1 dev enp2s0 metric 200

For normal traffic, the first route has the preferred metric.

This configuration can work well when the design is essentially:

Primary path
    +
Secondary path

But there is an important limitation.


When Route Metrics Are Not Enough

Consider an external client connecting directly to:

10.20.30.10

The request arrives through enp2s0.

However, the main routing table prefers:

default via 192.168.10.1 dev enp1s0 metric 100

The response could therefore attempt to leave through enp1s0.

Conceptually:

              REQUEST
Client ----------------------> enp2s0
                                |
                          Ubuntu Server
                                |
Client <---------------------- enp1s0
              RESPONSE

This is an asymmetric routing scenario.

Depending on the surrounding topology, stateful firewalls, NAT and upstream routing, it can produce symptoms such as:

  • SSH works on one IP but not the other;
  • TCP connections time out;
  • applications are reachable only through one interface;
  • connections establish and then stall;
  • packet captures show replies on an unexpected NIC.

If you encounter TCP connectivity symptoms, CorgiNetwork’s <a href=”https://corginetwork.com/netcat-explained/“>Netcat Explained</a> guide is useful because Netcat can test individual TCP and UDP ports instead of relying only on ICMP ping.

When each interface needs to use its own gateway consistently, policy routing becomes much more important.


What Is Source-Based Policy Routing?

Traditional destination-based routing asks:

Where is this packet going?

Source-based policy routing allows the system to additionally ask:

Where did this traffic originate?

We can therefore create a policy such as:

Source 192.168.10.10
        ↓
Routing Table 100
        ↓
Gateway 192.168.10.1

and:

Source 10.20.30.10
        ↓
Routing Table 200
        ↓
Gateway 10.20.30.1

Netplan supports policy-routing rules through routing-policy, while individual routes can be assigned to custom routing tables. See the <a href=”https://netplan.readthedocs.io/en/stable/netplan-yaml/” target=”_blank” rel=”noopener”>official Netplan configuration reference</a> for the supported routes and routing-policy properties.


Complete Netplan Configuration for Two NICs and Two Gateways

Consider this topology:

enp1s0
192.168.10.10/24
Gateway 192.168.10.1

enp2s0
10.20.30.10/24
Gateway 10.20.30.1

A source-policy configuration can look like this:

network:
  version: 2
  renderer: networkd

  ethernets:

    enp1s0:
      addresses:
        - 192.168.10.10/24

      routes:
        - to: 192.168.10.0/24
          scope: link
          table: 100

        - to: default
          via: 192.168.10.1
          table: 100

      routing-policy:
        - from: 192.168.10.10/32
          table: 100
          priority: 1000


    enp2s0:
      addresses:
        - 10.20.30.10/24

      routes:
        - to: 10.20.30.0/24
          scope: link
          table: 200

        - to: default
          via: 10.20.30.1
          table: 200

      routing-policy:
        - from: 10.20.30.10/32
          table: 200
          priority: 1100

This configuration expresses two important policies.

Traffic sourced from:

192.168.10.10

uses routing table:

100

while traffic sourced from:

10.20.30.10

uses:

200

Each table then contains its appropriate gateway.


Why Add the Connected Network to Each Table?

Notice this route:

- to: 192.168.10.0/24
  scope: link
  table: 100

and its equivalent for the second network.

A custom routing table should have enough information to reach the network containing its gateway and local peers.

The desired table looks conceptually like:

Table 100

192.168.10.0/24 dev enp1s0
default via 192.168.10.1

rather than containing only an isolated default route with insufficient supporting reachability.

The exact routes required depend on the topology, which is why copying a multi-homing configuration without understanding the network is risky.


Understanding routing-policy

This section:

routing-policy:
  - from: 192.168.10.10/32
    table: 100
    priority: 1000

means traffic matching the specified source is directed to the chosen routing table according to the policy rule.

After Netplan applies the configuration, inspect the result:

ip rule

A system might conceptually show:

0:       from all lookup local
1000:    from 192.168.10.10 lookup 100
1100:    from 10.20.30.10 lookup 200
32766:   from all lookup main
32767:   from all lookup default

Netplan documents policy-routing matching and priorities in its <a href=”https://netplan.readthedocs.io/en/stable/netplan-yaml/” target=”_blank” rel=”noopener”>YAML configuration reference</a>.


Route Metrics vs Policy Routing

This distinction is essential.

Route metrics answer:

Which competing route should normally have greater preference?

Example:

Gateway A → metric 100
Gateway B → metric 200

Policy routing answers:

Which routing table should this particular traffic use?

Example:

Source 192.168.10.10 → Table 100
Source 10.20.30.10   → Table 200

A useful mental model is:

Primary + backup
       ↓
Route metrics


Two independently routed interfaces
       ↓
Policy routing

This is not an absolute rule for every topology, but it is an excellent starting point.


Apply Netplan Safely

Network configuration changes can immediately disconnect a remote server.

Before modifying anything:

sudo cp -a /etc/netplan /etc/netplan.backup

Then edit the appropriate file under:

/etc/netplan/

Do not assume the filename is always:

50-cloud-init.yaml

Check first:

ls -la /etc/netplan/

Validate Before Applying

Run:

sudo netplan generate

If the YAML contains an error, correct it before applying anything.

YAML indentation is significant.

For example:

routes:
  - to: default
    via: 192.168.10.1

is structurally different from incorrectly indented YAML.

For the exact supported syntax, use Netplan’s <a href=”https://netplan.readthedocs.io/en/stable/netplan-yaml/” target=”_blank” rel=”noopener”>official YAML documentation</a> rather than relying on outdated examples.


Use netplan try for Remote Servers

When working over SSH, consider:

sudo netplan try

instead of immediately committing the configuration.

The <a href=”https://netplan.readthedocs.io/en/stable/netplan-try/” target=”_blank” rel=”noopener”>official netplan try documentation</a> explains that the command temporarily applies a configuration and can automatically roll it back if it is not confirmed.

This is particularly valuable when changing:

  • default gateways;
  • interface addresses;
  • routing tables;
  • policy-routing rules.

Even so, production servers should have an independent recovery mechanism such as a hypervisor console, cloud serial console, IPMI or provider recovery console.


Verify the Configuration

After applying the change, do not stop simply because Netplan reports no error.

Check the actual runtime state.

Addresses

ip -br addr

Main routes

ip route

Policy rules

ip rule

Table 100

ip route show table 100

Table 200

ip route show table 200

Every table

ip route show table all

Then ask Linux which route it will actually use.

ip route get 8.8.8.8 from 192.168.10.10

and:

ip route get 8.8.8.8 from 10.20.30.10

This is one of the most important validation steps in the entire configuration.


Test Each Interface Independently

Try:

ping -I 192.168.10.10 8.8.8.8

and:

ping -I 10.20.30.10 8.8.8.8

But remember that ping tests ICMP—not application connectivity.

For TCP testing:

nc -vz example.com 443

The <a href=”https://corginetwork.com/netcat-explained/“>CorgiNetwork Netcat guide</a> explains how Netcat can be used for direct port testing.

For HTTP/HTTPS:

curl --interface 192.168.10.10 https://example.com/

and:

curl --interface 10.20.30.10 https://example.com/

These tests help determine whether each source address has a functional path.


Use Packet Capture When Routing Still Looks Wrong

If Linux claims the correct route is being selected but connectivity still fails, observe the packets.

Capture on the first interface:

sudo tcpdump -ni enp1s0 host DESTINATION_IP

Then on the second:

sudo tcpdump -ni enp2s0 host DESTINATION_IP

Generate traffic and see which NIC actually carries it.

For deeper packet inspection, CorgiNetwork’s <a href=”https://corginetwork.com/wireshark-explained/“>Wireshark Explained</a> guide covers packet analysis concepts that complement command-line captures.

Wireshark’s own <a href=”https://www.wireshark.org/docs/wsug_html_chunked/” target=”_blank” rel=”noopener”>official User’s Guide</a> is also an excellent external reference when detailed packet analysis is required.


Don’t Forget the Firewall

Correct routing does not guarantee connectivity.

A firewall can still block the traffic.

For UFW:

sudo ufw status verbose

For nftables:

sudo nft list ruleset

CorgiNetwork’s <a href=”https://corginetwork.com/firewalls-explained/“>Firewalls Explained</a> guide explains the filtering layer in more detail.

Ubuntu also maintains official <a href=”https://documentation.ubuntu.com/server/how-to/security/firewalls/” target=”_blank” rel=”noopener”>firewall documentation</a> covering firewall configuration on Ubuntu Server.

Do not disable the firewall merely to make a multi-NIC configuration work. Identify whether the relevant traffic is actually being blocked.


Reverse Path Filtering on Multi-Homed Servers

Another issue worth checking is reverse path filtering.

Inspect:

sysctl net.ipv4.conf.all.rp_filter

and:

sysctl net.ipv4.conf.enp1s0.rp_filter
sysctl net.ipv4.conf.enp2s0.rp_filter

Reverse path validation can interact with asymmetric network designs.

However, do not immediately solve the problem by setting everything to zero.

First establish whether the routing architecture is correct and whether rp_filter is actually contributing to packet loss.

For kernel-level documentation, see the Linux kernel’s <a href=”https://docs.kernel.org/networking/ip-sysctl.html” target=”_blank” rel=”noopener”>IP sysctl documentation</a>, which documents rp_filter and other IPv4 networking parameters.


DHCP Can Recreate a Default Route

A particularly confusing situation occurs when one interface uses DHCP.

You configure the desired route manually, reboot, and an unwanted default route returns.

Inspect:

ip route

You may find a route associated with DHCP.

The reason is that DHCP can supply much more than an IP address. It can also provide gateway and DNS information.

CorgiNetwork’s <a href=”https://corginetwork.com/dhcp-explained/“>DHCP Explained</a> guide covers how DHCP configuration reaches clients.

In a multi-NIC design, determine exactly which component creates each default route.


DNS Problems Can Look Like Routing Problems

Suppose:

curl https://example.com

fails.

Before assuming policy routing is broken, check resolution:

getent ahosts example.com

or:

dig example.com

For the underlying resolution process, see CorgiNetwork’s <a href=”https://corginetwork.com/dns-explained/“>DNS Explained</a> guide.

When testing routing specifically, using a known destination IP can temporarily remove DNS from the equation.

Then return to hostname testing once IP connectivity is established.


Cloud Servers Require Two Levels of Routing Analysis

On a cloud VM, Netplan represents only part of the network.

A simplified path might be:

Ubuntu application
        ↓
Linux routing
        ↓
Virtual NIC
        ↓
Cloud subnet
        ↓
Cloud route table
        ↓
Security controls
        ↓
NAT / Internet gateway
        ↓
Internet

Therefore:

ip route

can be completely correct while the overall path still fails.

CorgiNetwork’s <a href=”https://corginetwork.com/cloud-networking-explained/“>Cloud Networking Explained</a> provides the conceptual bridge between operating-system networking and virtual cloud networks.

If you are comparing cloud implementations, see <a href=”https://corginetwork.com/aws-vs-azure-vs-google-cloud/“>AWS vs Azure vs Google Cloud</a>.

For provider-specific networking, prefer the official documentation for your platform, such as <a href=”https://docs.aws.amazon.com/vpc/” target=”_blank” rel=”noopener”>Amazon VPC documentation</a>, <a href=”https://learn.microsoft.com/en-us/azure/virtual-network/” target=”_blank” rel=”noopener”>Azure Virtual Network documentation</a>, or <a href=”https://cloud.google.com/vpc/docs” target=”_blank” rel=”noopener”>Google Cloud VPC documentation</a>.


Practical Troubleshooting Workflow

When an Ubuntu server with multiple interfaces behaves unpredictably, use this sequence.

1. Identify interfaces

ip -br link

2. Identify addresses

ip -br addr

3. Inspect the main routing table

ip route

4. Inspect policy rules

ip rule

5. Inspect all tables

ip route show table all

6. Ask the kernel which route it will use

ip route get DESTINATION_IP from SOURCE_IP

7. Test ICMP from each source

ping -I SOURCE_IP DESTINATION_IP

8. Test TCP

nc -vz DESTINATION 443

9. Test an application protocol

curl --interface SOURCE_IP https://example.com/

10. Capture packets

sudo tcpdump -ni any host DESTINATION_IP

This sequence moves the investigation from:

“My second interface doesn’t work.”

to:

“Linux selects table 200 correctly, sends the SYN through enp2s0, but no SYN-ACK returns.”

That is a much more actionable diagnosis.


Common Netplan Multiple-Route Mistakes

1. Adding Two Gateways Without Defining the Intended Behavior

Before configuring routes, decide whether you need:

  • preference;
  • failover;
  • source separation;
  • load distribution;
  • access to separate private networks.

Those are different networking problems.


2. Assuming Metrics Solve Source Routing

Metrics primarily establish route preference.

They do not automatically guarantee that traffic sourced from each NIC always returns through that NIC’s gateway.


3. Looking Only at ip route

Once policy routing exists, also inspect:

ip rule

and:

ip route show table all

4. Applying Changes Directly Over SSH

A malformed route can immediately remove remote access.

Use:

sudo netplan try

and maintain console access whenever possible.


5. Ignoring Automatically Generated Routes

DHCP, cloud-init, NetworkManager, VPN software and container platforms can all affect routing.


6. Treating Ping as Proof That Everything Works

ICMP connectivity does not prove that TCP, HTTPS or application traffic follows the correct path.

Use tools appropriate to the layer being tested.


Production Checklist

Before considering the configuration finished, verify:

Interfaces

ip -br addr

Main routes

ip route

Policy rules

ip rule

Custom tables

ip route show table 100
ip route show table 200

Route selection

ip route get DESTINATION from SOURCE

TCP connectivity

nc -vz DESTINATION PORT

Actual packet path

sudo tcpdump -ni any host DESTINATION

Finally, verify that the configuration survives a reboot during an appropriate maintenance window.

Persistent configuration matters just as much as immediate connectivity.


Frequently Asked Questions

Can Ubuntu have two default gateways?

Yes. Linux can maintain multiple default routes. The important question is how the system should select between them. Metrics, separate routing tables and policy rules provide different mechanisms for controlling that behavior.

What does a Netplan route metric do?

It assigns a preference value to a route. When otherwise competing routes are available, lower metrics generally represent more-preferred routes.

What is Netplan routing-policy?

It allows Netplan to define Linux policy-routing rules that select routing tables according to matching criteria such as source or destination addresses. See the <a href=”https://netplan.readthedocs.io/en/stable/netplan-yaml/” target=”_blank” rel=”noopener”>official Netplan YAML reference</a> for the current syntax.

When should I use policy routing instead of metrics?

Metrics are useful when the requirement is primarily route preference. Policy routing is useful when different traffic—such as packets from different source addresses—must follow different routing tables.

How do I check which route Linux will actually use?

Run:

ip route get DESTINATION_IP

For source-based routing:

ip route get DESTINATION_IP from SOURCE_IP

Why does traffic enter through one NIC and leave through another?

The main routing table may prefer a different default route for the return destination. This can create asymmetric routing. Inspect ip rule, all routing tables and the result of ip route get.

Why does my second default route return after reboot?

It may be generated by Netplan, DHCP, NetworkManager, systemd-networkd, cloud-init or another networking component. Identify its source before attempting to remove it.

Can a firewall cause symptoms that look like incorrect routing?

Absolutely. Correct routes do not guarantee that packets are permitted. Inspect both Linux firewall rules and any upstream/cloud security controls.


Conclusion

Fixing Netplan multiple default routes is not primarily about finding the right YAML snippet. It is about defining the routing behavior the server actually requires.

If the requirement is:

Primary gateway
      +
Backup gateway

route metrics may be enough.

If the requirement is:

Traffic from IP A → Gateway A

Traffic from IP B → Gateway B

you are dealing with source-based policy routing.

The most important diagnostic commands are:

ip addr
ip route
ip rule
ip route show table all
ip route get

Then use ping, nc, curl and tcpdump to verify what happens to real traffic.

The combination of Netplan configuration and Linux routing diagnostics provides a far more reliable solution than repeatedly changing default gateways until connectivity appears to work.

For your next troubleshooting step, CorgiNetwork’s <a href=”https://corginetwork.com/linux-network-tools-guide/“>Linux Network Tools Guide</a>, <a href=”https://corginetwork.com/netcat-explained/“>Netcat Explained</a>, and <a href=”https://corginetwork.com/wireshark-explained/“>Wireshark Explained</a> provide the tools needed to investigate the packet path from the command line all the way to packet-level analysis.

Leave a Reply

Your email address will not be published. Required fields are marked *