tailscale/tailscale · error
the tailnet lock key of the current node must be one of the
Error message
the tailnet lock key of the current node must be one of the trusted keys during initialization
What it means
During `tailscale lock init`, the CLI parses the supplied trusted keys and verifies that one of them matches the current node's own tailnet-lock key (st.PublicKey.KeyID()). If no key's ID equals the node key ID, initialization aborts, because the node signing the init update must itself be trusted or the tailnet would lock out its own signer.
Source
Thrown at cmd/tailscale/cli/tailnet-lock.go:141
keys, disablementValues, err := parseTLArgs(args, true, true)
if err != nil {
return err
}
// Common mistake: Not specifying the current node's key as one of the trusted keys.
foundSelfKey := false
for _, k := range keys {
keyID, err := k.ID()
if err != nil {
return err
}
if bytes.Equal(keyID, st.PublicKey.KeyID()) {
foundSelfKey = true
break
}
}
if !foundSelfKey {
return errors.New("the tailnet lock key of the current node must be one of the trusted keys during initialization")
}
fmt.Println("You are initializing tailnet lock with the following trusted signing keys:")
for _, k := range keys {
fmt.Printf(" - tlpub:%x (%s key)\n", k.Public, k.Kind.String())
}
fmt.Println()
if !nlInitArgs.confirm {
fmt.Printf("%d disablement secrets will be generated.\n", nlInitArgs.numDisablements)
if nlInitArgs.disablementForSupport {
fmt.Println("A disablement secret will be generated and transmitted to Tailscale support.")
}
genSupportFlag := ""
if nlInitArgs.disablementForSupport {
genSupportFlag = "--gen-disablement-for-support "
}View on GitHub (pinned to cfe32b8be6)
Solutions
- Get this node's key from `tailscale lock status` (or `tailscale lock init` help text) and include its tlpub in the init arguments
- Re-run: `tailscale lock init tlpub:<this-node> tlpub:<others...>`
- Prefer running init on the node whose key you intend to trust first
Example fix
# before $ tailscale lock init tlpub:<node-b-key> # after $ tailscale lock init tlpub:<node-a-key-this-node> tlpub:<node-b-key>
Defensive patterns
Strategy: validation
Validate before calling
st, _ := localClient.TailnetLockStatus(ctx)
selfID := st.PublicKey.KeyID()
for _, k := range keys {
id, _ := k.ID()
if bytes.Equal(id, selfID) {
return nil // ok to init
}
}
return errors.New("current node key missing from init key set") Prevention
- Always include the output of `tailscale lock status` local key in init args
- Run init from the node whose key you list first
- Automate key collection instead of hand-copying tlpub strings
When it happens
Trigger: Running `tailscale lock init tlpub:<other-node-key>` where the listed keys do not include the key of the node running the command; computing the wrong KeyID (k.ID() error aside, mismatch of bytes); pasting trusted keys from a different node.
Common situations: Admin initializes lock from node A but only lists node B's signing key; keys copied from documentation or another tailnet; key typo when transcribing tlpub values.
Related errors
- cannot remove the last trusted signing key; use 'tailscale l
- cannot remove local trusted signing key while resigning; run
- Error: provided key was already wrapped
- tailnet lock is already enabled
- tailnet lock is not enabled
AI-assisted analysis of tailscale/tailscale@cfe32b8be6 (2026-08-15).
Data as JSON: /api/errors/a5de35719395e792.
Report an issue: GitHub.