Your route line comes back rejected, and the advice you find says to enable IP forwarding. Those two things sit at different stages of the problem. Forwarding decides whether a host may move packets between interfaces; it has no opinion about whether the destination you typed is a valid network. Fix the prefix first, because forwarding will not rescue an address and mask that disagree.

What the parser is actually complaining about

A destination written as address plus mask has to describe a network, and a network starts with zeroed host bits. When the address you supply still carries a value in the host portion, the pair is internally inconsistent: 172.20.130.0 looks tidy because it ends in zero, but zero in the fourth octet is not the only thing that matters. The third octet is the one holding stray bits here.

Tools handle that inconsistency differently. Strict parsers refuse the line and name host bits. Lenient parsers mask the address down and install something you did not ask for, which is worse, because the configuration now routes a range you never intended. Python's ipaddress module exposes the choice directly: strict network parsing raises an error, and strict=False masks the host bits out. Your client may be strict, lenient or inconsistent between versions, so read the message instead of trusting a habit.

Work the example through by hand

Take a tunnel that needs to reach 172.20.130.0 with a /20 mask. A /20 borrows four bits from the third octet, so that octet only counts in steps of 16: 0, 16, 32 and onward up to 240. The value 130 falls between 128 and 143, which means the enclosing network begins at 172.20.128.0, not at 172.20.130.0 with the last octet cleared.

Written out, the block runs from 172.20.128.0 to 172.20.143.255 and holds 4,096 addresses. Feeding the same values to a non-strict parser shows the substitution it would have made on your behalf:

$ python3 -c "import ipaddress; n=ipaddress.ip_network('172.20.130.0/20', strict=False); print(n, n.num_addresses)"
172.20.128.0/20 4096

Decide which destination you actually meant

The rejected line usually hides one of three intentions, and only you can pick. If the tunnel needs the whole block, write 172.20.128.0/20, the canonical network address. If the tunnel needs just the 130 segment, the mask was wrong and 172.20.130.0/24 is the honest form. If a single machine is the target, an IPv4 host route is /32 and no mask arithmetic is involved.

Each of those authorizes a different amount of traffic, and that is the real reason not to widen the mask until the complaint stops. A /16 accepts the line almost anywhere and sends traffic toward destinations you never meant to route through the tunnel. Write the narrowest prefix that matches the intent, then confirm it against the next hop you expect, not against the parser's silence.

Why forwarding was never the fix

A rejected route never reaches the forwarding path, so toggling net.ipv4.ip_forward cannot change the outcome. That setting matters later, when the host must pass packets between interfaces, and turning it on before the table is correct only changes which stage fails next.

Two other things often get blamed at the same point. The route may be accepted and still lose to a more specific route, and a firewall rule may drop traffic after a correct lookup. Keep the stages separate: syntax, installation, selection, filtering. Working on the wrong stage feels productive because every change restarts something.

Check the installed route and the path it wins

Once the client accepts the line, look at what it installed and which route the kernel picks for a representative address inside the block. If the installed prefix differs from what you wrote, a normalizer acted on your behalf.

Query a member address as well as one outside the block, so the comparison is meaningful rather than a single reassuring line:

ip -4 route show 172.20.128.0/20
ip -4 route get 172.20.140.10
ip -4 route get 172.20.200.10

The third query should fall outside the tunnel if your prefix is right, and when it does not, the route you built is broader than you think. Record what the prefix was meant to cover before you touch the next setting, because a route that parses and a path that works remain separate observations.

Artihkkalat mat laktásit