Transmission proxy settings did not exist in any current form until version 4.1.0, released on 27 January 2026, whose notes say: "Added support for using a proxy server for web connections." The words "web connections" are precise. The new proxy_url key routes HTTP(S) requests, such as announces to an HTTP tracker, and nothing else. Peer connections never go through it. For a reviewer, that turns the usual question around: with Transmission the honest egress statement is that the swarm sees the host's own address, and the proxy, if any, only changes who the tracker sees.
Transmission is the default client on several Linux desktops and runs as transmission-daemon on many NAS boxes and small servers, so it often turns up on infrastructure nobody chose it for. This guide covers the configuration as documented for 4.1.3, released on 30 June 2026, and what to do if peers must leave through a controlled exit.
Decide what the proxy is for
Before editing anything, write down which of these the change is meant to achieve:
- Tracker requests leave through an approved exit, for example because policy routes all outbound HTTP through a named proxy.
proxy_urldoes this. - All of the client's traffic leaves through one exit.
proxy_urlcannot do this. See the section on controlled exits below. - Nobody should see the host's address. No proxy setting in any client achieves this reliably, and Transmission does not try. If the concern is copyright exposure, the client projects themselves point to a VPN; qBittorrent's wiki says it outright. The real control is distributing only what you may.
Separately, someone has to confirm that BitTorrent is permitted on this network and that the content, a distribution image, an open-source release, an archive item or a dataset, is lawful to share. On our network, peer-to-peer traffic for lawful content is fine on residential exits and on dedicated ISP and datacenter addresses without a traffic meter. Using our network for unauthorised sharing is excluded by the acceptable use policy.
What proxy_url covers in Transmission 4.1
The configuration documentation for 4.1.3 describes the key as: "Proxy for HTTP(S) requests (for example, requests to tracker). Format [scheme]://[host]:[port], where scheme is one of: http, https, socks4, socks4h, socks5, socks5h. If null, Transmission respects the CURL environment variables. If empty string, no proxy is used."
The client's source shows why the scope is narrow. libtransmission/web.cc sets CURLOPT_PROXY on its libcurl handle, and only HTTP(S) requests go through libcurl. So:
| Traffic | Uses proxy_url |
|---|---|
Announces and scrapes to http:// and https:// trackers |
Yes |
| Other HTTP(S) requests the client makes through libcurl | Yes |
| Peer connections over TCP | No |
| Peer connections over uTP | No |
udp:// trackers |
No |
| DHT | No |
Choosing socks5h rather than http changes the protocol to the gateway and moves DNS resolution of the tracker name to the proxy. It does not widen the coverage.
This also settles the cost question in an unusual direction. Because only tracker traffic crosses the proxy, a Transmission install pointed at a metered exit uses very little of it, a few requests per announce interval. The payload, in both directions, leaves from the host. That is cheap and it is not IP masking, and the review should say both.
Setting it on transmission-daemon
There is no field in the GTK, Qt or macOS preferences; the client's source at 4.1.3 contains no proxy control in any of the three layouts. Edit settings.json instead. Two rules from the documentation matter:
- Stop the client before editing, "otherwise settings will be reverted" when it writes its own copy on exit.
- The daemon reloads on
SIGHUP, so a runningtransmission-daemoncan pick up a change without a restart.
Since 4.1 the keys are moving to snake_case, and the old kebab-case names still work. A minimal entry, with the host authenticated by IP allowlist so no credential sits in the file:
{
"proxy_url": "socks5h://PROXY_HOST:PROXY_PORT"
}
Merge that key into the existing file rather than replacing it. Then reload:
sudo kill -HUP "$(pidof transmission-daemon)"
Whether Transmission accepts user:password@ inside proxy_url is not documented. libcurl accepts that form in CURLOPT_PROXY, but that does not prove Transmission passes it through unchanged, so test it before relying on it. Allowlisting avoids the question; IP allowlist vs username and password covers when that is the better choice anyway.
One platform-specific trap: when proxy_url is null, Transmission "respects the CURL environment variables". A daemon started by a unit file or container that inherits a host-wide HTTPS_PROXY or ALL_PROXY will send its tracker requests through that proxy without anyone configuring Transmission at all. Set proxy_url to an explicit value, or to an empty string for no proxy, so the behaviour is visible in the file rather than inherited from the environment.
The older proxy keys
Transmission's documentation still lists proxy-* keys from the 1.4x era, covering HTTP, SOCKS4 and SOCKS5, under Legacy Options. Guides written before 2026 often describe them as current. Do not configure them on 4.1 and do not cite them in a review. If an existing settings.json carries them, remove them so nobody later assumes they do something.
When peers must leave through a controlled exit
If the requirement is the second one above, every connection through one approved exit, Transmission's own settings cannot meet it. The options are at the host or the choice of client:
- Route the host, not the application. Run the daemon in a network namespace or container whose only route out is a tunnel to the approved exit. The client then needs no proxy setting at all, and the egress statement is a property of the network, which is easier to audit.
- Use a client that proxies peers. qBittorrent and Deluge do, over SOCKS5, with the caveats in their own guides. Expect peer traffic through a metered proxy to cost the full payload twice, which our gigabyte definition lets you estimate.
- Do not seed from this host. If the job is fetching an image, the distribution's HTTPS mirror and checksum file do it in one transfer.
Note what does not work: an egress firewall that only allows the proxy endpoint would leave Transmission able to reach its HTTP trackers and unable to reach any peer, which is a broken client, not a proxied one.
Verifying what the daemon sends
With a lawful torrent active, list the daemon's TCP sockets:
ss -tnp | grep transmission
Expect connections to the gateway only while the client talks to an HTTP tracker, and many established connections to peer addresses on arbitrary ports. Those peer connections are the expected result, not a misconfiguration. For UDP, which ss cannot attribute by destination, capture:
sudo tcpdump -ni any 'udp and not port 53 and not net 127.0.0.0/8'
DHT and uTP traffic will appear there. Confirm the exit the tracker sees with the proxy checker, which reports the address the gateway presents for the same host.
What goes in the change record
- Purpose stated: tracker requests through an approved exit, not peer masking
- BitTorrent permitted on this network; content source recorded
- Transmission 4.1.0 or later confirmed on the host
-
proxy_urlset explicitly, or set to an empty string, never left to inherit the environment - Legacy
proxy-*keys removed fromsettings.json - Authentication by IP allowlist, or
user:password@tested on this build - Statement in the review that peers, uTP, UDP trackers and DHT leave from the host's own address
Transmission is one of two clients in this series that can only proxy tracker traffic; aria2 is the other. The full comparison is in torrent client proxy support compared.