A command reaches 10.8.0.5 inside the VPN namespace without complaint, and the same command fails the moment it uses a hostname. The namespace has its own interfaces, routes and sockets; it does not have its own resolver file. Unless something puts one there, the process inside reads the host's /etc/resolv.conf and asks a server that may be unreachable from that network stack.

That is a file-selection problem rather than a routing problem, which is exactly why the numeric destination still works.

Check the resolver view the process actually gets

Do not assume the shell you used is equivalent to the process you are debugging. A graphical application, a systemd unit, and a container may each enter a different mount or network context. Run the lookup through the same launch path, and print the resolver file from inside it.

For a namespace created with ip netns add, the read-only check is short:

ip netns exec vpn cat /etc/resolv.conf

Note whether the result names a reachable address, a loopback stub, or a symlink that points somewhere with different reachability.

What the exec helper actually mounts

The ip-netns tool documents per-namespace configuration under /etc/netns/NAME/. When it launches a process, the helper creates a mount namespace and bind-mounts those files over their usual paths, so the process sees the namespace-specific copy. That is a convenience of this specific launcher. Entering a network namespace by another route, such as unshare or a container runtime, does not reproduce it automatically.

A loopback resolver is the trap here: 127.0.0.53 means the namespace's own loopback, not the host's stub. A stub listening only in the host namespace does not become a service in the new one.

Pick a resolver the namespace can reach

Whatever server the file names still needs a route from that namespace. A public resolver can answer public names and still fail for an internal zone, because the private service is reachable only through the tunnel. Check the route at the same time as the address, not after the lookup has already failed.

Applications with their own resolver, such as one using DNS over HTTPS, may ignore the file entirely. If the tool has its own DNS setting, changing resolv.conf will not affect it, and the namespace was never the problem.

Write the file in the right place

Create the per-namespace file under /etc/netns/NAME/resolv.conf and let the launcher present it. Keep it minimal: one or two reachable servers and the search domains the task needs. Do not edit the host's generated resolver file to fix a view meant for one group of processes, because that changes every application on the machine. If the host uses a resolver manager, configure the namespace path through that manager rather than fighting it.

Record the file contents in the runbook. Otherwise the next person tests the host's resolver, sees a working answer, and concludes the namespace is fine.

Re-test the whole path

Test inside the namespace with a numeric address, an internal name, and a public name. That sequence separates reachability from resolution and separates internal zones from public ones. Then recreate the namespace and repeat, because a file that only exists in a running instance disappears with it.

Confirm the process, not the shell, is receiving the file. A lookup that works from an interactive shell and fails from a service is a mount-context finding, and it is worth writing down before the next incident rather than rediscovering it from scratch.

Ebitabo ebifaananyi