Introduction to FRP Reverse Proxy Troubleshooting
FRP (Fast Reverse Proxy) is a popular open-source tool that allows you to expose local services behind NAT or firewalls to the public internet. While FRP is generally reliable, developers frequently encounter configuration issues, connection failures, and performance bottlenecks during deployment. This tutorial walks you through the most common FRP issues and provides actionable fixes with practical examples.
What Is FRP and Why Troubleshooting Matters
FRP consists of two components: the frps server (running on a public-facing machine) and the frpc client (running on your local machine). The client establishes an outbound connection to the server, creating a tunnel through which external traffic can reach your local services. Because FRP involves networking, authentication, encryption, and proxying layers, misconfigurations can manifest in subtle ways — silent connection drops, authentication errors, or traffic that simply never arrives.
Effective troubleshooting matters because FRP is often used in production scenarios such as remote development environments, IoT device access, and exposing internal APIs. A broken tunnel can mean lost productivity or inaccessible services. Understanding the failure modes helps you resolve issues quickly and design more resilient deployments.
Common Issues and Their Fixes
1. Client Cannot Connect to Server
The most frequent issue is the frpc client failing to establish a connection with frps. This typically stems from incorrect server addresses, closed ports, or token mismatches.
Symptoms: The client logs show "login to server failed" or repeated reconnection attempts.
Fix: Verify the server address, port, and authentication token in your client configuration.
# frpc.toml - Client configuration
serverAddr = "203.0.113.10"
serverPort = 7000
auth.token = "your-secret-token-here"
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
Check the corresponding server configuration to ensure the port and token match:
# frps.toml - Server configuration
bindPort = 7000
auth.token = "your-secret-token-here"
Additionally, confirm that port 7000 is open in your server's firewall and cloud provider security group. On Linux, you can verify with:
# Check if frps is listening
sudo ss -tlnp | grep 7000
# Open the port in ufw
sudo ufw allow 7000/tcp
2. Authentication Token Mismatch
If the auth.token values differ between client and server, the connection will be rejected. This is a common issue when copying configurations between environments.
Fix: Ensure both files use the identical token string. Avoid trailing whitespace or newline characters. You can also enable more verbose logging to confirm the cause:
# frpc.toml
log.level = "debug"
log.to = "./frpc.log"
With debug logging enabled, restart the client and inspect the log file:
./frpc -c frpc.toml
tail -f frpc.log
You should see a clear authentication error if the token is wrong.
3. Port Already in Use on the Server
When multiple clients map to the same remotePort, or when another service occupies that port, FRP will fail to bind the proxy.
Symptoms: The client connects successfully, but the proxy shows a "port already used" error in the logs.
Fix: Either choose a different remote port or allow port reuse on the server:
# frps.toml
allowPorts = [
{ start = 6000, end = 7000 }
]
On the client side, pick a unique remote port:
[[proxies]]
name = "web-service"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8080
remotePort = 6080
If you need to allow the same port to be reused across different proxies, you can enable portReuse, but use this with caution to avoid traffic routing conflicts.
4. HTTP and HTTPS Proxy Not Working
For HTTP-based proxies, FRP relies on the vhostHTTPPort and vhostHTTPSPort settings on the server. If these are not configured, HTTP proxies will not function.
Fix: Configure the virtual host ports on the server:
# frps.toml
vhostHTTPPort = 80
vhostHTTPSPort = 443
Then define an HTTP proxy on the client with a custom domain:
# frpc.toml
[[proxies]]
name = "web"
type = "http"
localPort = 8080
customDomains = ["dev.example.com"]
Ensure that dev.example.com has a DNS A record pointing to your FRP server's public IP address. You can verify DNS resolution with:
dig dev.example.com +short
nslookup dev.example.com
5. TLS Connection Failures
When TLS is enabled between client and server, certificate or protocol mismatches can prevent the tunnel from forming.
Fix: Enable TLS consistently on both sides. On the client:
# frpc.toml
transport.tls.enable = true
transport.tls.serverName = "frps.example.com"
If you are using a self-signed certificate on the server, you must disable strict verification on the client:
transport.tls.disableCustomTLSFirstByte = false
On the server, configure the TLS certificate paths:
# frps.toml
transport.tls.force = true
transport.tls.certFile = "/etc/frp/server.crt"
transport.tls.keyFile = "/etc/frp/server.key"
6. Dashboard Not Accessible
FRP provides a web dashboard for monitoring active proxies. If it is not loading, the dashboard port may not be configured or may be blocked by a firewall.
Fix: Enable the dashboard in the server configuration:
# frps.toml
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "strong-password"
Access it at http://your-server-ip:7500 and log in with the configured credentials. Make sure port 7500 is open in your firewall.
7. STUN and P2P Connections Failing
FRP supports P2P (peer-to-peer) connections using STUN to bypass the server for direct client-to-client traffic. This can fail when both peers are behind symmetric NAT.
Fix: Configure a STUN server and enable the visitor proxy:
# frpc.toml (on the exposing client)
[[proxies]]
name = "p2p-ssh"
type = "xtcp"
localIP = "127.0.0.1"
localPort = 22
# frpc.toml (on the visiting client)
[[visitors]]
name = "p2p-ssh-visitor"
type = "xtcp"
serverName = "p2p-ssh"
secretKey = "shared-secret"
bindAddr = "127.0.0.1"
bindPort = 6000
If P2P fails, FRP will fall back to a server-relayed connection. You can monitor the connection type in the dashboard or logs.
8. Performance and Latency Issues
High latency or low throughput through FRP can result from compression and encryption overhead, or from insufficient bandwidth on the server.
Fix: Tune transport settings based on your workload. For high-bandwidth scenarios, disable compression:
# frpc.toml
transport.useCompression = false
transport.useEncryption = true
For low-bandwidth, high-latency connections, enable compression to reduce payload size:
transport.useCompression = true
You can also adjust the connection pool size for better concurrency:
# frps.toml
transport.maxPoolCount = 10
Best Practices for Reliable FRP Deployments
- Use strong authentication tokens: Generate long, random tokens and store them securely. Never commit them to public repositories.
- Enable TLS: Always encrypt traffic between the client and server, especially when transmitting sensitive data.
- Restrict allowed ports: Use the
allowPortssetting on the server to limit which ports clients can bind, reducing the attack surface. - Monitor with the dashboard: Regularly check the FRP dashboard for proxy status, traffic statistics, and connection health.
- Run FRP as a systemd service: This ensures automatic restarts on failure and startup on boot.
- Keep FRP updated: New releases include bug fixes and security patches. Test updates in a staging environment before deploying to production.
- Use meaningful proxy names: Descriptive names make it easier to identify proxies in logs and the dashboard.
- Log rotation: Configure log rotation to prevent log files from consuming disk space over time.
Here is an example systemd service file for frps:
# /etc/systemd/system/frps.service
[Unit]
Description=frp server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.toml
Restart=on-failure
RestartSec=5s
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable frps
sudo systemctl start frps
sudo systemctl status frps
Debugging Workflow Summary
When troubleshooting FRP, follow a systematic approach:
- Check client and server logs with debug logging enabled.
- Verify network connectivity between client and server using
pingandtelnetornc. - Confirm that configuration files match on both sides, especially tokens and ports.
- Inspect firewall rules on both the server and any cloud provider security groups.
- Use the FRP dashboard to verify proxy status and traffic flow.
- Test with a minimal configuration first, then add complexity incrementally.
A quick connectivity test from the client machine:
# Test if the FRP server port is reachable
nc -zv 203.0.113.10 7000
# Test if the remote proxy port is accessible externally
curl -v http://203.0.113.10:6080
Conclusion
FRP is a powerful and flexible reverse proxy tool, but its multi-layered architecture means that issues can arise at the network, authentication, configuration, or transport level. By understanding the common failure modes — connection failures, token mismatches, port conflicts, HTTP vhost misconfiguration, TLS errors, and performance bottlenecks — you can diagnose and resolve problems efficiently. Combining these fixes with best practices like TLS encryption, systemd service management, dashboard monitoring, and restricted port ranges will help you build a robust and secure FRP deployment that remains reliable under real-world conditions.