Nodes are individual devices connected to your Headscale network. This guide covers listing, monitoring, and managing these devices.
Listing Nodes
Docker Command
Helper Script
Headplane GUI
docker exec headscale headscale nodes list
Output: ID | Name | User | IP | Status | Last Seen
1 | alice-laptop | alice | 100.64.0.1 | online | 2024-01-15 10:30:00
2 | bob-desktop | bob | 100.64.0.2 | online | 2024-01-15 10:28:00
3 | server-prod | admin | 100.64.0.10 | online | 2024-01-15 10:29:00
4 | phone-android | alice | 100.64.0.5 | offline| 2024-01-14 18:00:00
./scripts/headscale.sh nodes list
Open http://localhost:3001/admin/
Go to Nodes page
View all nodes with:
Hostname
User
IP addresses (IPv4 and IPv6)
Online/offline status
Last seen timestamp
Operating system
Tailscale version
Each node has several attributes:
Node ID : Unique identifier
Hostname : Device name (can be customized)
User : Owner of the node
IP Addresses : Both IPv4 (100.64.x.x) and IPv6 (fd7a:115c:a1e0::)
Status : Online or offline
Last Seen : Timestamp of last contact with server
Tags : ACL tags applied to the node
Routes : Advertised subnet routes or exit node status
Deleting Nodes
Deleting a node removes it from the network. The device will need to reconnect with a new pre-auth key.
Find the node ID
docker exec headscale headscale nodes list
Note the ID number of the node you want to delete.
Delete the node
Docker Command
Helper Script
Headplane GUI
docker exec headscale headscale nodes delete --identifier NODE_ID
Example: docker exec headscale headscale nodes delete --identifier 4
./scripts/headscale.sh nodes delete NODE_ID
Example: ./scripts/headscale.sh nodes delete 4
Open http://localhost:3001/admin/
Go to Nodes page
Find the node
Click Delete button
Confirm deletion
Verify deletion
docker exec headscale headscale nodes list
The deleted node should no longer appear.
Expiring Offline Nodes
Remove all nodes that have been offline for an extended period:
Docker Command
Helper Script
docker exec headscale headscale nodes expire --all-offline
./scripts/headscale.sh nodes expire
This is useful for cleaning up devices that are no longer in use, such as test devices or decommissioned hardware.
Registering Nodes Manually
If a node was added without a pre-auth key, it needs manual registration:
docker exec headscale headscale nodes register --user USERNAME --key NODEKEY
Most setups use pre-auth keys for automatic registration. Manual registration is rarely needed.
Renaming Nodes
Node hostnames are set by the device and can be changed:
On the Device
# Disconnect
sudo tailscale down
# Reconnect with new hostname
sudo tailscale up \
--login-server http://localhost:8000 \
--authkey YOUR_KEY \
--hostname my-new-name
sudo /Applications/Tailscale.app/Contents/MacOS/Tailscale up \
--login-server=http://localhost:8000 \
--authkey=YOUR_KEY \
--hostname=my-new-name
tailscale up -- login - server http: // localhost: 8000 -- authkey YOUR_KEY -- hostname my - new-name
Using Headplane GUI
Open http://localhost:3001/admin/
Go to Nodes page
Click on the node
Edit the hostname field
Save changes
Tagging Nodes
Tags organize nodes and apply ACL policies. Tags are set during connection:
Create Tagged Pre-Auth Key
docker exec headscale headscale preauthkeys create \
--user myuser \
--reusable \
--expiration 24h \
--tags tag:personal
docker exec headscale headscale preauthkeys create \
--user myuser \
--reusable \
--expiration 24h \
--tags tag:servers,tag:production
{
"tagOwners" : {
"tag:personal" : [ "group:admins" ],
"tag:servers" : [ "group:admins" ],
"tag:guests" : [ "group:admins" ]
},
"acls" : [
{
"action" : "accept" ,
"src" : [ "tag:personal" ],
"dst" : [ "tag:servers:22,80,443" ],
"comment" : "Personal devices can SSH and access web services on servers"
},
{
"action" : "accept" ,
"src" : [ "tag:guests" ],
"dst" : [ "tag:servers:80,443" ],
"comment" : "Guests can only access web services"
}
]
}
Monitoring Node Status
Check Node Connectivity
From a connected device:
View Status
Check Network
View Peers
Test Ping
View Node Details in Headplane
Open http://localhost:3001/admin/
Go to Nodes page
Click on any node to see:
Full connection details
IP addresses (IPv4 and IPv6)
Advertised routes
Tags applied
Online/offline status
Last handshake time
Operating system and version
Node States
Online
Node is actively connected and can communicate with the network.
Indicators :
tailscale status shows connected
Last seen timestamp is recent (< 5 minutes)
Headplane shows green status
Offline
Node is disconnected and cannot be reached.
Common causes :
Device is powered off
Tailscale service stopped
Network connectivity issues
Firewall blocking traffic
Troubleshooting :
# On the device
sudo systemctl status tailscaled # Linux
tailscale status # Check connection
sudo tailscale up # Reconnect
Expired
Node was removed due to inactivity (from nodes expire command).
Recovery : Reconnect the device with a new pre-auth key.
Ephemeral Nodes
Ephemeral nodes are automatically removed when they disconnect.
Create Ephemeral Pre-Auth Key
docker exec headscale headscale preauthkeys create \
--user myuser \
--ephemeral \
--expiration 1h
Use Cases
Temporary access : Guest devices that shouldn’t persist
CI/CD runners : Build agents that connect temporarily
Testing : Devices used for short-term testing
One-time tasks : Scripts or automation that run once
Connect with Ephemeral Key
sudo tailscale up \
--login-server http://localhost:8000 \
--authkey EPHEMERAL_KEY \
--hostname temp-device
When this device disconnects, it’s automatically removed from the network.
Node IP Assignment
Headscale assigns IP addresses from configured prefixes:
prefixes :
v6 : fd7a:115c:a1e0::/48
v4 : 100.64.0.0/10
IP Address Range
IPv4 : 100.64.0.0 - 100.127.255.255 (4,194,304 addresses)
IPv6 : fd7a:115c:a1e0:: range
Stable IPs
Once assigned, a node keeps its IP address even after reconnecting (unless the node is deleted).
Bulk Operations
List All Online Nodes
docker exec headscale headscale nodes list | grep online
List All Offline Nodes
docker exec headscale headscale nodes list | grep offline
Count Total Nodes
docker exec headscale headscale nodes list | tail -n +2 | wc -l
Export Node List
docker exec headscale headscale nodes list > nodes- $( date +%Y%m%d ) .txt
Security Best Practices
Regular Audits Review connected nodes weekly: docker exec headscale headscale nodes list
Remove any unknown or unused devices.
Expire Old Nodes Clean up offline nodes regularly: docker exec headscale headscale nodes expire --all-offline
Use Tags Apply tags for better access control: --tags tag:personal,tag:trusted
Monitor Access Check who’s connected in real-time:
Use Headplane GUI dashboard
Review last seen timestamps
Investigate unexpected connections
Troubleshooting
Node Not Appearing
Check device is connected
On the device: Should show “Connected” or list other nodes.
Verify pre-auth key worked
docker exec headscale headscale nodes list
The new device should appear in the list.
Check server logs
docker compose logs -f headscale
Look for connection attempts or errors.
Cannot Delete Node
Error : “node not found”
# List nodes to get correct ID
docker exec headscale headscale nodes list
# Use the exact ID from the list
docker exec headscale headscale nodes delete --identifier 5
Node Shows Offline but Device is Online
# On the device, reconnect
sudo tailscale down
sudo tailscale up --login-server http://localhost:8000
# Check connectivity
tailscale netcheck
Duplicate Hostnames
Multiple nodes can have the same hostname. Use MagicDNS with full domain:
# Instead of
ping myserver
# Use
ping myserver.headscale.net
Or rename devices to unique names:
sudo tailscale up --login-server http://localhost:8000 --hostname myserver-1
Next Steps