Skip to main content
Nodes are individual devices connected to your Headscale network. This guide covers listing, monitoring, and managing these devices.

Listing Nodes

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

Node Information

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.
1

Find the node ID

docker exec headscale headscale nodes list
Note the ID number of the node you want to delete.
2

Delete the node

docker exec headscale headscale nodes delete --identifier NODE_ID
Example:
docker exec headscale headscale nodes delete --identifier 4
3

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 exec headscale headscale nodes expire --all-offline
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

Using Headplane GUI

  1. Open http://localhost:3001/admin/
  2. Go to Nodes page
  3. Click on the node
  4. Edit the hostname field
  5. 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

Multiple Tags

docker exec headscale headscale preauthkeys create \
  --user myuser \
  --reusable \
  --expiration 24h \
  --tags tag:servers,tag:production

Using Tags in ACL Policy

config/policy.json
{
  "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:
tailscale status

View Node Details in Headplane

  1. Open http://localhost:3001/admin/
  2. Go to Nodes page
  3. 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:
config/config.yaml
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

1

Check device is connected

On the device:
tailscale status
Should show “Connected” or list other nodes.
2

Verify pre-auth key worked

docker exec headscale headscale nodes list
The new device should appear in the list.
3

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

Build docs developers (and LLMs) love