Trace the connection before changing the firewall
FiveM uses more than a website connection. An HTTPS reverse proxy can handle the connect endpoint, but the game endpoint also needs raw TCP/UDP reachability. A proxied DNS record alone does not transport every game protocol.
The procedures here follow Cfx.re proxy setup and the static infrastructure IP policy . Configuration examples are templates, not changes applied to your server.
What a joining client does
- Resolve the connect endpoint from server-list
connectEndPoints, a cached join/history address, or the explicitconnectargument. - Fetch
GET /info.json, then sendinitConnecttoPOST /client. A successful response supplies a connection token. - Request
getEndpointsand choose a game endpoint. With several advertised endpoints, the client may choose one; every advertised address must work. - Request
getConfigurationand download resources from/files/*on that endpoint or the file-server override. - Send a UDP info request, an ENet connection and UDP handshake, then load the game. Additional multiplexed TCP/UDP side channels may follow.
A bare server.example means HTTP on port30120, not HTTPS on443. server.example:30121 selects that port. A full https://server.example/ retains its scheme/default port. For an HTTPS connect proxy, use connect "https://server.example/" or its join URL.
Direct hosting and basic tests
endpoint_add_udp "0.0.0.0:30120"
endpoint_add_tcp "0.0.0.0:30120"The port must be free and permitted through the host firewall, provider firewall and any NAT port forwarding. A home connection behind carrier-grade NAT may not accept inbound connections even when the local router has a forwarding rule. Keep txAdmin’s administration interface restricted to intended administrators; it is not the public game port.
Check locally, then from another network. info.json returning valid server metadata proves one HTTP path, not UDP or a complete join. Likewise, a UDP nc invocation without a protocol response is not proof that FiveM is reachable. Perform an actual client join and identify the first failing stage from both client and server logs. Redact tokens, endpoints and identifiers before publishing diagnostics.
HTTPS connect proxy
This minimal nginx HTTP-context example preserves request headers and HTTP/1.1 for connection deferrals. Replace the backend and certificate paths. Validate nginx configuration before reloading it.
upstream fivem_connect_backend {
server 10.10.0.20:30120;
}
server {
listen 443 ssl;
server_name play.example.com;
ssl_certificate /etc/ssl/play/fullchain.pem;
ssl_certificate_key /etc/ssl/play/private.key;
location / {
proxy_pass http://fivem_connect_backend;
proxy_http_version 1.1;
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
}
}# server.cfg; use the ACTUAL proxy source address, not this placeholder.
set sv_forceIndirectListing true
set sv_listingHostOverride "play.example.com"
set sv_proxyIPRanges "10.10.0.10/32"
# Advertise a public reachable game endpoint, not a private backend IP.
set sv_endpoints "203.0.113.20:30120"203.0.113.20 is an example address, not a runnable public endpoint. Replace it. sv_proxyIPRanges is a trust boundary: matching sources may provide X-Real-IP and bypass the corresponding rate limiter. Never set it to every address. If a CDN precedes nginx, configure that proxy’s verified real-IP chain; otherwise nginx sees the CDN address, not the player.
sv_listingIpOverride helps the listing backend select the query IP when it cannot infer it, such as a multihomed or restricted origin. It is not the frontend game endpoint. sv_forceIndirectListing changes advertising; it does not make an otherwise exposed origin undiscoverable or provide DDoS immunity.
Optional file caching
A file proxy is separate from connection authentication. Keep /client, tokens, deferrals and player-specific responses out of generic shared caching rules. The official CDN pattern uses a secret global obfuscation key and a file-server override:
# Configure a private, generated value rather than this placeholder.
set adhesive_cdnKey "REPLACE_WITH_PRIVATE_GENERATED_VALUE"
fileserver_add ".*" "https://play.example.com/files"Configure caching only for /files/, preserve the full request URI/query in the cache key, and test the exact hashed file URLs before and after a resource update. Global-key file obfuscation changes cacheability; it is not authorization to expose other server files. sv_httpFileServerProxyOnly true restricts the origin file server to sv_proxyIPRanges, so enabling it before the proxy works will break downloads.
For nginx, define a bounded proxy_cache_path in the HTTP context, use proxy_cache_lock on to prevent duplicate fills, proxy_cache_revalidate on, and a URI-sensitive proxy_cache_key. The source’s long-lived cache example relies on versioned asset requests. Do not impose an arbitrary year-long cache on mutable filenames without checking invalidation and authorization behavior.
Raw game endpoint proxy
nginx’s stream module can proxy TCP and UDP on the same port. This is a top-level stream configuration, not an ordinary HTTP location or sites-enabled snippet.
stream {
upstream fivem_game_backend {
server 10.10.0.20:30120;
}
server {
listen 30120;
proxy_pass fivem_game_backend;
}
server {
listen 30120 udp reuseport;
proxy_pass fivem_game_backend;
}
}Advertise the proxy’s public address through sv_endpoints. Ensure the installed nginx build actually has the stream module, and restrict direct origin access without blocking traffic from the proxy or required platform infrastructure. Test packet loss, reconnects and long sessions, not just the first metadata request.
Local TLS termination on the game host
The upstream local-TLS design leaves UDP on30120 and moves the internal TCP listener to30121. Declare UDP before TCP in this setup:
endpoint_add_udp "0.0.0.0:30120"
endpoint_add_tcp "0.0.0.0:30121"Then place an nginx TLS HTTP listener on30120 forwarding to http://127.0.0.1:30121, with an appropriate certificate and the header/HTTP settings above. Use a publicly trusted certificate for a public hostname where possible. A self-signed certificate requires deliberate trust handling; do not disable certificate verification globally to make a test pass.
Block external access to the internal30121 port while retaining loopback/proxy access. The upstream examples use ufw deny 30121/tcp, an iptables INPUT rule or a Windows inbound firewall rule. Apply the rule through the firewall manager you actually use, after reviewing existing rules and preserving SSH/RDP access. A blanket INPUT drop may also affect loopback under a different ruleset. Record the exact added rule so rollback removes only that rule—not the entire firewall.
A development self-signed certificate can be generated with openssl req -x509 -newkey rsa:2048 -nodes -days 365 -keyout local-test.key -out local-test.crt. Protect the private key. These filenames are test outputs; do not overwrite a production certificate.
Listing infrastructure and static IPs
Cfx publishes polling addresses at static.cfx.re/ips.txt . With a restrictive firewall or upstream DDoS service, maintain access for all currently published addresses. New entries have a documented grace period of at least one month before they start sending traffic. Treat a failed download as a failure to update, not as an empty allowlist; validate entries and keep the previous known-good set.
A transient browser-contact warning may clear; repeated failures can remove listing visibility. Check outbound connectivity, inbound query reachability, forwarded ports and the infrastructure allowlist. sv_master1 "" changes browser join behavior but does not de-list or securely hide a server. For a private development server, restrict its actual network access.
Verification and rollback
Check /info.json, /dynamic.json, /players.json and the expected POST-only response for a GET to /client, accounting for intentional privacy and sv_requestParanoia policy. Then test an actual deferral, resource download, UDP connection and sustained game session from another network. Browser JSON success alone is insufficient.
Advanced deployments can put the HTTP proxy behind an ingress, share a hostname using precise location rules, or implement a custom initConnect selector. These require preserving the complete connection/token handoff and do not turn raw game traffic into HTTP.
Keep the original configuration and a verified administrative path. On failure, restore only the changed listener, advertised endpoints, trusted proxy ranges and cache override, then reload/restart the affected service. Do not disable all security rules. Use server configuration and client diagnostics to identify the exact failure rather than adding unrelated tuning flags.
Server absent from the list: isolate listing from joining
First perform an external FiveM Direct Connect and spawn test. If it fails, record the first failing stage above and inspect the active endpoint, firewall and NAT. If it succeeds, inspect the active listing configuration, sv_master1, project metadata, heartbeat errors and client filters using the server-list diagnostic table.
Do not treat /info.json, a TCP port checker or an open txAdmin page as proof of a successful game connection. A proxy’s advertised endpoints must all work for the selected track; a local loopback result does not test an outside client. The official server support guide is the source for listing/private-server checks.
For curl error 7 or handshake failures, retain the failing destination and process: handshake triage separates a game endpoint from a resource’s external HTTP service. Avoid changing unrelated ports, keys or caches before establishing which connection actually failed.