Global vs Local Discovery
Before two Syncthing devices can sync, they must find each other. Discovery is the mechanism that maps a Device ID to a reachable address. Syncthing supports two modes: local (LAN) and global (internet).
Know exactly which discovery servers your devices contact and how to disable global discovery for air-gapped or maximum-privacy deployments.
| Discovery Mode | Protocol | Range | Port | Privacy |
|---|---|---|---|---|
| Local | IPv4/IPv6 multicast | LAN only | UDP 21027 | High — stays on LAN |
| Global | HTTPS to discovery.syncthing.net | Internet | TCP 443 | Moderate — IP revealed to Syncthing's servers |
| Static address | None (direct) | Any | Any | Highest — no discovery server used |
| Custom discovery server | HTTPS | Any | Configurable | Full control |
How Local Discovery Works
sequenceDiagram
participant DevA as Device A (LAN)
participant Multicast as 239.21.0.1:21027 (UDP multicast)
participant DevB as Device B (LAN)
DevA->>Multicast: "I am K3X2R... reachable at 192.168.1.10:22000"
Multicast->>DevB: Broadcast announcement
DevB-->>DevA: Direct TCP/TLS connection on port 22000
Local discovery requires no internet access and no configuration. Devices on the same LAN find each other automatically within seconds.
# Confirm UDP 21027 is listening
ss -ulnp | grep 21027
# Watch local discovery announcements in logs
journalctl --user -u syncthing -f | grep -i "local discovery"
How Global Discovery Works
When peers are on different networks, Syncthing announces its current IP and port to Syncthing's hosted discovery servers:
- Device A starts, contacts
https://discovery.syncthing.net - Registers its Device ID → IP:port mapping
- Device B queries the discovery server for Device A's Device ID
- Both devices receive each other's addresses and establish a direct connection
The discovery server sees your IP address and Device ID, but not your files or file names. All data transfer is P2P and encrypted.
Configuring Discovery in config.xml
<options>
<!-- Local discovery (LAN multicast) -->
<localAnnounceEnabled>true</localAnnounceEnabled>
<localAnnouncePort>21027</localAnnouncePort>
<localAnnounceMCAddr>[ff12::8384]:21027</localAnnounceMCAddr>
<!-- Global discovery -->
<globalAnnounceEnabled>true</globalAnnounceEnabled>
<globalAnnounceServers>default</globalAnnounceServers>
</options>
The value default expands to https://discovery.syncthing.net/v2/?id=... (Syncthing's hosted servers).
Disabling Global Discovery (Air-Gapped / Privacy Mode)
<options>
<globalAnnounceEnabled>false</globalAnnounceEnabled>
<localAnnounceEnabled>true</localAnnounceEnabled>
</options>
With global discovery off, you must configure static addresses for remote peers:
<device id="K3X2R..." name="remote-vps">
<address>tcp://203.0.113.45:22000</address>
</device>
Running a Self-Hosted Discovery Server
For organizations that want control over discovery:
# Build or download stdiscosrv
go install github.com/syncthing/syncthing/cmd/stdiscosrv@latest
# Run (generates its own TLS cert)
stdiscosrv -listen :8443
# Get the server's Device ID
stdiscosrv --device-id
In each client's config.xml:
<globalAnnounceServers>https://your-discovery.example.com:8443/?id=SERVER_DEVICE_ID</globalAnnounceServers>
Discovery Troubleshooting Matrix
| Symptom | Cause | Fix |
|---|---|---|
| Peer shows as Disconnected on LAN | UDP 21027 blocked | Allow ufw allow 21027/udp on both hosts |
| Peer never connects over internet | Global discovery disabled or unreachable | Enable global discovery or configure static address |
| Constant reconnection attempts | Wrong static IP configured | Update <address> entry with correct IP/port |
| "Discovery error" in logs | DNS or HTTPS blocked to discovery servers | Whitelist discovery.syncthing.net or use custom server |