The most common and most damaging mistake on an onion-service VPS is leaving the webserver listening on a public interface. Tor delivers requests to your service over the loopback interface: in your torrc you set something like HiddenServicePort 80 127.0.0.1:8080, and Tor forwards onion traffic to 127.0.0.1:8080. If nginx also binds 0.0.0.0:8080 (or :80), the exact same content is reachable directly over the clearnet by anyone who scans your VPS IP. Scanners like Shodan and Censys index those pages, and a single matching string, favicon hash, or page title links your onion address to your real IP. The hidden service is then pointless.
Bind nginx to loopback only. In the server block, the listen directive must name the loopback address explicitly:
server {
listen 127.0.0.1:8080;
server_name _;
# ... onion content ...
}Never use a bare listen 8080; on an onion vhost, because that binds all interfaces. After reloading nginx, verify with ss -tlnp that the socket shows 127.0.0.1:8080 and not 0.0.0.0:8080 or *:8080. Back this up at the firewall layer with a default-deny inbound policy that only permits the SSH port you actually use; nothing else should accept connections from the public interface. On a clean offshore VPS with full root access you control both layers, so there is no shared edge proxy quietly re-exposing your service.
If the box serves both a clearnet site and a separate onion service, give each its own server block on its own loopback port, and never let the onion vhost answer the default server_name on a public listener. Test from outside the VPS with curl http://YOUR_VPS_IP:8080/; it must time out or be refused, not return your page.