juanfont/headscale · error
deleting api key: %w
Error message
deleting api key: %w
What it means
Transport error from 'headscale apikeys delete': the DELETE request (addressed by prefix in the URL path, possibly resolved from --id via apiKeyPrefixForID) failed at the HTTP layer before a response arrived. Note the delete-by-id path performs an extra list call first, so a failure here means the actual DELETE call failed, not the prefix lookup.
Source
Thrown at cmd/headscale/cli/api_key.go:186
RunE: clientRunE(func(ctx context.Context, client *clientv1.ClientWithResponses, cmd *cobra.Command, args []string) error {
id, prefix, err := apiKeyIDOrPrefix(cmd)
if err != nil {
return err
}
// The DELETE route addresses the key by its prefix in the path. When the
// user deletes by --id we resolve the id to its (masked) prefix first,
// since the path segment is required and a query-only id cannot be routed.
if prefix == "" {
prefix, err = apiKeyPrefixForID(ctx, client, id)
if err != nil {
return err
}
}
resp, err := client.DeleteApiKeyWithResponse(ctx, prefix, &clientv1.DeleteApiKeyParams{})
if err != nil {
return fmt.Errorf("deleting api key: %w", err)
}
if resp.StatusCode() != http.StatusOK {
return apiError(resp.StatusCode(), resp.ApplicationproblemJSONDefault)
}
return printOutput(cmd, resp.JSON200, "Key deleted")
}),
}
// apiKeyPrefixForID resolves an API key id to its display prefix by listing the
// keys. The DELETE endpoint addresses keys by prefix in the URL path, so a
// delete by --id needs the prefix; the returned masked prefix is accepted by
// the server's lookup.
func apiKeyPrefixForID(
ctx context.Context,
client *clientv1.ClientWithResponses,
id uint64,View on GitHub (pinned to 565fd254d0)
Solutions
- Verify connectivity ('headscale health')
- Confirm address/TLS config, then retry the delete
- If deleting by --id failed after the prefix lookup succeeded, re-run with --prefix directly to skip the extra list round trip
Defensive patterns
Strategy: retry
Validate before calling
// prefer prefix to skip the id->prefix resolution round trip
if prefix != "" { /* single DELETE call, fewer failure points */ } Try / catch
if _, err := client.DeleteApiKeyWithResponse(ctx, prefix, params); err != nil {
if isTransportError(err) { /* verify with list, then retry once */ }
} Prevention
- Pass --prefix directly in automation to avoid the extra list dependency
- Confirm deletes with a follow-up 'apikeys list' rather than blind retries
When it happens
Trigger: Deleting an API key while the server is unreachable or restarting; TLS/cert mismatch; context timeout on a slow link.
Common situations: Automation running deletes against a server mid-restart; CLI pointing at a stale address after a server migration; proxy interference with DELETE verbs.
Related errors
- listing api keys: %w
- creating api key: %w
- expiring api key: %w
- registering node: %w
- approving auth request: %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/01648ea5ff31f5df.
Report an issue: GitHub.