Skip to content

Troubleshooting Guide

Solutions for common r-vpn problems.


Connection Problems

"Failed to connect" or timeout

Symptoms: The client hangs at Connecting to wss://... and eventually times out.

Check:

  1. Server port is accessible:

    # From a different machine
    nc -zv your-server.com 443
    curl -I https://your-server.com/api/v1/ws
    

  2. Firewall allows port 443:

    sudo ufw status  # UFW
    sudo iptables -L -n | grep 443  # iptables
    

  3. TLS certificate is valid:

    openssl s_client -connect your-server.com:443 -servername your-server.com </dev/null 2>/dev/null | openssl x509 -noout -dates
    

  4. WebSocket path is correct. Clients connect to {websocket_path} (e.g., /api/v1/ws). If your server uses a different path, update client.toml.


"TLS handshake failed"

Symptoms: Client shows TLS handshake failed or certificate verify failed.

Causes and solutions:

  1. Let's Encrypt certificate not renewed:

    sudo certbot certificates
    sudo systemctl reload rvpn-server
    

  2. Wrong hostname in server_address:

    # The hostname must match the certificate
    server_address = "wss://your-server.com/api/v1/ws"  # Certificate must be for your-server.com
    

  3. SNI mismatch:

    # If connecting through a CDN or by IP
    server_address = "wss://10.0.0.1/api/v1/ws"
    sni_hostname   = "your-server.com"  # Certificate hostname
    

  4. iOS: Sandbox cert verification issue (older builds): Ensure you have rebuilt the Rust library after updating. On iOS, cert verification uses the system trust store via SecTrustEvaluateWithError.


"Connection refused" immediately

Symptoms: Client fails instantly with Connection refused.

Check:

# Is the server running?
sudo systemctl status rvpn-server

# Is it listening on the right port?
sudo ss -tlnp | grep 443

# Can you connect locally?
curl -I http://127.0.0.1:8443/api/v1/ws


"X3DH handshake failed"

Symptoms: Connection starts but fails during encryption setup.

Causes:

  1. Prekey bundle mismatch: Clients and servers must use the same prekey bundle. If the server rotated keys and the client has an old bundle, this can fail.

    # On server: regenerate prekey bundle
    rvpn-server prekey-bundle
    # Distribute new prekey-bundle.json to clients
    

  2. Identity key changed: If the server identity key was regenerated, all clients need the new prekey bundle.


"Too many connections" or rate limit exceeded

Symptoms: Connection refused or Rate limited after connecting successfully for a while.

Check server rate limits:

[server.rate_limit]
max_connections_per_ip    = 5
max_handshakes_per_minute = 10

Each client connection consumes one slot. If you have many devices, increase these values.


TUN Mode Problems

Client connects but has no internet access

Check 1: IP forwarding on server:

sysctl net.ipv4.ip_forward
# Must return: net.ipv4.ip_forward = 1

If not enabled:

sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf

Check 2: NAT rules on server:

sudo iptables -t nat -L POSTROUTING -v
sudo iptables -L FORWARD -v

You should see MASQUERADE rules and FORWARD ACCEPT rules.

If missing:

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT

Check 3: Server security group/firewall allows outbound: The server must be able to initiate outbound connections to any IP on any port for NAT to work.

Check 4: NAT enabled in server.toml:

[server.network]
nat_enabled = true

Check 5: Client routes:

# On client, check routing table
ip route show  # Linux
route -n get 0.0.0.0  # macOS

# Default route should point to tunnel interface


Traffic flows out but nothing returns

Symptoms: You can ping external IPs but get no response. Server logs show frames being relayed but no "Relay completed".

Root cause: SOCKS5 response sent before tunnel was ready.

Fix: This was a bug in older versions. Rebuild and redeploy:

cd rvpn-ios && ./build_rust.sh

Check server logs:

INFO  rvpn_server: Listening on 0.0.0.0:443
INFO  rvpn_server: WebSocket path: /api/v1/ws
INFO  rvpn_server: TUN mode enabled

If TUN mode is not enabled, clients in TUN mode will fail to connect properly.


TUN interface not created on server

Check:

sudo ip addr show tun0
sudo ip link show tun0

If interface does not exist: 1. Verify enabled = true in [server.tun] 2. Check server logs for errors during interface creation 3. Try a different interface name in case of naming conflict


Client cannot ping server TUN IP

Check:

# On server
ping 10.200.0.1  # From server to itself via tun0

# On client
ping 10.200.0.1  # Client should be able to reach server's TUN IP

If client cannot reach 10.200.0.1, the tunnel is not established properly.


SOCKS5 Mode Problems

Apps not routing through proxy

Check 1: Proxy is running:

curl --socks5 127.0.0.1:1080 https://api.ipify.org

If this returns your VPN server IP, the proxy is working.

Check 2: System proxy settings: Ensure your system or app is configured to use 127.0.0.1:1080 as SOCKS5 proxy.

Check 3: Browser proxy settings: Chrome and Edge use system proxy settings. Firefox has its own proxy settings.

Check 4: App-specific issues: Some apps do not support SOCKS5 (only HTTP proxy). Use a SOCKS5-to-HTTP proxy adapter or switch to TUN mode.


DNS leaks in SOCKS5 mode

Symptoms: DNS leak test shows your ISP DNS, not VPN DNS.

Fix: Enable the DNS proxy:

[dns_proxy]
enabled        = true
listen_address = "127.0.0.1:53"

Configure your system DNS to 127.0.0.1. See DNS Leak Prevention for detailed setup.

Chrome-specific issue: Chrome uses its own secure DNS resolver by default, which bypasses the system DNS and the VPN tunnel. - On desktop/Android: Go to Settings → Privacy and security → Security → Use secure DNS and turn it off. - Clear Chrome's DNS cache: visit chrome://net-internals/#dns and click Clear host cache. - On iOS: Force-close Chrome or clear browsing data to flush its cache.


Multiplexed mode issues

Symptoms: Some apps or websites fail to load, timeout, or behave inconsistently while the proxy appears to be running.

Fix: Multiplexed mode shares a single WebSocket tunnel across all flows. If a website or app is incompatible with this behaviour, switch to legacy (non-multiplexed) mode temporarily:

[socks5]
multiplex = false

Important: Legacy mode opens one WebSocket connection per TCP flow. A busy browser can easily exhaust the server's max_connections_per_ip limit. If you plan to use legacy mode regularly, ask your server administrator to raise the limits:

[server.rate_limit]
max_connections_per_ip    = 500
max_handshakes_per_minute = 2000

Slow connection speeds

Possible causes:

  1. High latency: The VPN server is geographically distant
  2. Server overload: Too many connections to one server
  3. Bandwidth limit: Server's upstream is saturated
  4. MTU issues: Packet fragmentation on high-latency links

Solutions:

  1. Lower MTU in client.toml:

    [tun]
    mtu = 1280
    

  2. Try a different server closer to your location

  3. Check server load: uptime, htop
  4. Disable IPv6 if not needed:
    [network]
    ipv6_enabled = false
    prefer_ipv4  = true
    

iOS App Problems

"Failed to start VPN"

Check: 1. Server address includes wss:// (not https://) 2. Identity key is generated (Settings -> Identity) 3. Prekey bundle is imported 4. Server is running and accessible

Rebuild Rust library:

cd rvpn-ios && ./build_rust.sh


Connection drops frequently

Possible causes:

  1. Network instability (Wi-Fi to cellular handoff)
  2. iOS suspending the app in background
  3. VPN profile being revoked

Solutions: 1. Enable "Always-on VPN" in iOS Settings -> VPN 2. Check for iOS updates 3. Rebuild and reinstall the app


No IP assigned

Cause: The server's DHCP pool is exhausted.

Fix: Increase the DHCP range on the server:

[server.network]
dhcp_range = "10.200.0.0/22"  # /22 gives 1022 IPs instead of 254

Or disconnect unused clients.


Split Tunnel Problems

Bypassed traffic still going through VPN

Check:

[split_tunnel]
enabled = true  # Must be true for any bypass to work
builtin_bypass_countries = ["CN"]

Verify rules are loaded: The client logs should show bypass rules on startup:

INFO  rvpn_client: Split tunnel enabled, X networks bypassed

Check routing table:

ip route show  # Linux
route -n get 0.0.0.0  # macOS

Ensure bypassed networks are not in the VPN routing table.


Streaming service still blocking

Causes: 1. Streaming services may use GPS/locale signals, not just IP 2. Account payment currency and history affect content 3. CDN IPs may not match country bypass data

Solutions: 1. Clear browser/app cookies and cache 2. Use a browser extension to spoof timezone and locale 3. Full tunnel mode may be needed (bypass nothing)


Performance Problems

High latency through VPN

Check latency to server:

ping your-server.com

If latency is high even to the server, the issue is geographic distance, not the VPN.

Optimise: 1. Use a server closer to your location 2. Lower MTU if on satellite or high-latency link:

[tun]
mtu = 1280

Low throughput

Check: 1. Server bandwidth: iperf3 test to server 2. Client hardware: encryption is CPU-intensive on older devices 3. Network congestion

Optimise:

[performance]
worker_threads        = 4
crypto_worker_count   = 4
recv_buffer_size      = 262144
send_buffer_size      = 262144


Getting More Information

Enable debug logging

For detailed client logs:

RUST_LOG=debug rvpn -c ~/.config/rvpn/client.toml

For server logs:

RUST_LOG=debug sudo rvpn-server -c /etc/rvpn/server.toml

Check system logs

# systemd journal
sudo journalctl -u rvpn-server -f

# kernel logs (for TUN interface issues)
dmesg | grep tun

Verify network paths

# Trace path to server
traceroute your-server.com

# Trace path from server to target
# (on server) sudo tcpdump -i tun0 -n

Common log messages

Log message Meaning
Listening on 0.0.0.0:443 Server started successfully
WebSocket path: /api/v1/ws WebSocket endpoint configured
TUN mode enabled Server TUN interface active
X3DH handshake complete Encryption established
NAT enabled Server will masquerade client traffic
Relay completed One data relay session finished
Too many connections Rate limit exceeded