Two identifiers show up in every ZeroTier conversation, and they look similar enough to be confused in a chat window. The node ID names a device. The network ID names the virtual network that device wants to join. Joining takes the second, and authorizing a member takes the first.

Two identifiers, two jobs

A node identity is generated when the service first runs on a machine, and it is a ten-character hexadecimal address. It stays with that installation until the identity files are removed, which is why a reinstall can produce a new member that nobody has approved. A network ID is sixteen hexadecimal characters, and it identifies a virtual network rather than a machine. The controller that owns the network is itself a node, which is why the first ten characters of the network ID match the controller's address.

Neither value is a secret and neither is a substitute for the other. Sharing the network ID with every participant is normal; sharing a node ID identifies one device to the controller.

Read each value from the command that reports it

One command reports the identity of the local service, and a different one reports the networks it has joined. Asking the wrong command for a value is how people end up pasting a network ID into a membership list.

zerotier-cli info
zerotier-cli status
zerotier-cli listnetworks

The first prints the node address and whether the service is online. The second adds version and port information. The third lists joined networks with their network IDs, status and assigned addresses, and it is the only one that should be used when you need the network ID.

Join with the network, authorize with the node

The join command takes the network ID supplied by whoever runs the controller. Getting a positive response from the command means the request was submitted, not that membership was granted on a private network.

After the join, the administrator authorizes the device by its node ID in the member list for that network. They do not need the network ID again, and they cannot authorize a device by its hostname, because the identity is the address. If you are the administrator, read the member list and match the node address against the request. A request naming a network but no node address is not actionable.

The shared prefix has a reason

Because a network ID begins with the controller's node address, the same ten characters appear in both places. That is a routing convenience, not a hint that the two values are interchangeable.

It also explains why a controller's identity matters more than its display name. Restoring a controller under a new identity creates a different address space, so the networks defined under the old one are not the same networks even if the names are reused.

Keep the controller identity in your backup alongside its configuration. Treating that identity as a label to be regenerated turns a restore into a redesign.

Verify the result, not the command output

A successful join is the beginning of the check, not the end of it. Look at the network entry afterwards and read three fields: the status, the assigned address and the network ID.

zerotier-cli listnetworks -j
ip -br addr show | grep zt
ping -c 2 10.147.20.5

The first command prints the same list in a parseable form, which is easier to compare against what the administrator expected. The second confirms the interface received an address, and the third tests a peer on the network rather than the local state.

If the entry says ACCESS_DENIED, the node ID is not authorized. If it says NOT_FOUND, the network ID is wrong. If it says OK with no address, the controller's address assignment is the next question, and none of those three is answered by joining again.

འབྲེལ་བའི་རྩོམ་ཡིག