I put a lab network inside a VRF on a Linux host, so test traffic could not reach anything else on the machine. A proxy on the same host listened on 0.0.0.0:9000.
Every connection from inside the VRF was refused. The listener was up, the ACL permitted the source range, the route existed, and a packet capture showed the SYN arriving on the VRF interface.
A socket bound to the wildcard address lives in the default L3 domain. A packet arriving in a VRF is in a different one, and by default the kernel will not match it to that socket. Nothing logs a reason, because as far as the network stack is concerned there is no listener for that packet.
One sysctl allows the match:
sudo sysctl -w net.ipv4.tcp_l3mdev_accept=1
Persist it, or it disappears at the next reboot and the lab breaks in a way that looks like an application fault:
echo 'net.ipv4.tcp_l3mdev_accept=1' | sudo tee /etc/sysctl.d/10-vrf.conf
There is a net.ipv4.udp_l3mdev_accept equivalent, which matters as soon as anything in the lab resolves names against a host-local resolver.
Worth knowing what it costs: this weakens the isolation the VRF was built for. A wildcard-bound service becomes reachable from every L3 domain, not only the one you had in mind. If a service should serve the lab alone, bind it to the VRF explicitly rather than opening the wildcard match globally.
The general lesson: when a connection is refused but the packet demonstrably arrives, stop checking the route and start checking whether the listener is in the same namespace, VRF or address family as the traffic.