Guide
Adding a custom bootstrap node
Every Tox client ships with a built-in list of bootstrap nodes, and for most people that list just works. You need this page when it doesn't: when the shipped nodes are blocked on your network, when they have gone stale, or when you would rather choose the node you hand your IP address to.
The three values you need
Any client asks for the same three things — an address, a port, and the node's DHT public key. For this node:
| Field | Value |
|---|---|
| Address | node.toxbootstrap.org (or 144.91.88.86) |
| UDP port | 33445 |
| TCP relay ports | 443, 3389, 33445 |
| Public key | 451C6B9B11DAF61336D8C5892BB00210EEFF3E9C58BE1827BFD442C163155B79 |
One thing that trips people up: the key above is a DHT public key, not a Tox ID. They are different keys with different lifetimes. A regular client generates a fresh DHT key every time it starts, which is exactly why you cannot use a friend's client as a bootstrap node — the key you wrote down stops being valid the moment they restart. A bootstrap daemon keeps the same key permanently, which is the whole point of running one.
qTox (Windows, Linux, macOS, FreeBSD)
qTox supports custom bootstrap nodes from its settings interface. Open Settings, find the advanced or connection section, and add the address, port and public key from the table above. Add it alongside the existing nodes rather than replacing them — if this node ever goes down, you want your client to have somewhere else to go.
qTox also reads an optional node list file from its settings directory, typically ~/.config/tox/ on Linux and %APPDATA%\tox\ on Windows. The exact filename and format have changed between releases, so check the user manual bundled with your version before hand-editing anything. Note also that the qTox repository was archived in early 2025: it still runs, but do not expect new releases.
If your network blocks UDP, turn on TCP-only mode in the same settings area. Your client will then reach the network through TCP relays, including this one on port 443 or 3389.
Toxic (terminal, ncurses)
Toxic downloads and caches a node list, and lets you point it at a different one. The relevant option lives in ~/.config/tox/toxic.conf — run man toxic.conf for the current option name in your build, since it has been renamed across versions. Supply a JSON file in the same shape as the one this site produces:
{
"nodes": [
{
"ipv4": "144.91.88.86",
"port": 33445,
"tcp_ports": [443, 3389, 33445],
"public_key": "451C6B9B11DAF61336D8C5892BB00210EEFF3E9C58BE1827BFD442C163155B79",
"maintainer": "OnionSearchEngine",
"location": "DE"
}
]
}
Toxic is written in C with an ncurses interface and runs on machines with no graphical environment at all, which makes it the practical choice on a VPS or over SSH.
Android
aTox and TRIfA both bootstrap from a built-in list and neither exposes a comfortable UI for editing it. Your options, in order of how much patience they require:
- Leave the defaults alone. If the app connects, there is nothing to fix.
- If the app offers a proxy or TCP-only setting, enable it — that routes you through TCP relays and often solves connection failures on mobile networks that mangle UDP.
- If your client build supports importing a node list, feed it the JSON above.
Be aware that Tox on mobile is hard on the battery. A peer-to-peer client has to stay reachable, which means holding connections open rather than waiting on a push notification server. That is the cost of not having a central server in the loop.
tox-bootstrapd (running your own node)
If you are running your own bootstrap daemon, you also want a few nodes to bootstrap from. On most Linux distributions the config lives at /etc/tox-bootstrapd.conf and uses libconfig syntax:
bootstrap_nodes = (
{
address = "node.toxbootstrap.org"
port = 33445
public_key = "451C6B9B11DAF61336D8C5892BB00210EEFF3E9C58BE1827BFD442C163155B79"
}
)
Then restart and confirm the daemon is actually listening:
sudo systemctl restart tox-bootstrapd
sudo systemctl status tox-bootstrapd
ss --listening --numeric --processes | grep 33445
Budget for the bandwidth before you commit. The Tox project's own estimate for a very popular long-established node was around 700 GiB per month, split evenly between inbound and outbound, and that figure was published in 2016 and has grown since. A new node sees a small fraction of that, but the number only goes one way over time.
Developers: the toxcore API
If you are building on toxcore directly, bootstrapping is two calls. tox_bootstrap() registers the node for UDP DHT queries; tox_add_tcp_relay() registers it as a TCP relay. Call both with the same node — they serve different purposes and a client behind a UDP-blocking firewall needs the second one.
Tox_Err_Bootstrap err;
const char *host = "node.toxbootstrap.org";
uint8_t key[TOX_PUBLIC_KEY_SIZE]; /* decoded from the hex string above */
tox_bootstrap(tox, host, 33445, key, &err);
tox_add_tcp_relay(tox, host, 443, key, &err);
Two practices the Tox maintainers ask for, and they are worth following: ship a node list with your application rather than fetching one at every start, and cache whatever you do fetch on the user's device. Node list servers get hammered otherwise, and they are also the first thing a censor blocks — an app that cannot start without reaching a web server is an app that stops working exactly when people need it most.
When it still won't connect
- Check the key character by character. A single wrong hex digit fails silently: the client sends queries and the node ignores them. This is the most common cause by far.
- Try TCP on port 443. If UDP is being dropped, nothing else you change will help.
- Add more nodes. One node is a single point of failure. Take four or five from the Tox wiki list.
- Give it a minute. Bootstrapping is not instant; the client has to find peers, then find your contacts among them.
- Check whether your contact is simply offline. With no server to hold messages, a message to an offline peer waits in your client until they reappear.