juanfont/headscale · warning
either --id or --prefix must be provided: %w
Error message
either --id or --prefix must be provided: %w
What it means
Validation error from apiKeyIDOrPrefix: the user invoked an API-key subcommand (expire/delete) with neither --id nor --prefix. At least one identifier is required because the server routes the request to a specific key. It wraps the sentinel errMissingParameter so callers can test for it with errors.Is.
Source
Thrown at cmd/headscale/cli/api_key.go:122
}
if resp.StatusCode() != http.StatusOK {
return apiError(resp.StatusCode(), resp.ApplicationproblemJSONDefault)
}
return printOutput(cmd, resp.JSON200.ApiKey, resp.JSON200.ApiKey)
}),
}
// apiKeyIDOrPrefix reads --id and --prefix from cmd and validates that
// exactly one is provided.
func apiKeyIDOrPrefix(cmd *cobra.Command) (uint64, string, error) {
id, _ := cmd.Flags().GetUint64("id")
prefix, _ := cmd.Flags().GetString("prefix")
switch {
case id == 0 && prefix == "":
return 0, "", fmt.Errorf("either --id or --prefix must be provided: %w", errMissingParameter)
case id != 0 && prefix != "":
return 0, "", fmt.Errorf("only one of --id or --prefix can be provided: %w", errMissingParameter)
}
return id, prefix, nil
}
var expireAPIKeyCmd = &cobra.Command{
Use: cmdExpire,
Short: "Expire an ApiKey",
Aliases: []string{"revoke", aliasExp, "e"},
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
}
body := clientv1.ExpireApiKeyJSONRequestBody{}View on GitHub (pinned to 565fd254d0)
Solutions
- Pass exactly one of --id <n> or --prefix <prefix>
- Find valid values first with 'headscale apikeys list'
- For scripts, capture the id/prefix from the create or list output programmatically
Example fix
# before headscale apikeys expire # after headscale apikeys expire --prefix abcdef1234
Defensive patterns
Strategy: validation
Validate before calling
id, _ := cmd.Flags().GetUint64("id")
prefix, _ := cmd.Flags().GetString("prefix")
if id == 0 && prefix == "" {
return fmt.Errorf("pass --id or --prefix; see 'headscale apikeys list'")
} Try / catch
if err := cmd.Execute(); err != nil {
if errors.Is(err, cli.ErrMissingParameter) { /* print usage hint and exit 2 */ }
} Prevention
- Default scripts to --prefix captured at creation time
- Validate flags before invoking the CLI in shell scripts (set -u + explicit arg checks)
When it happens
Trigger: Running 'headscale apikeys expire' or 'headscale apikeys delete' with no --id and no --prefix flags (id==0 and prefix=="").
Common situations: Scripts written for an older CLI that took a positional key argument; users assuming the command operates on the most recent key; typos in flag names so both flags read as unset.
Related errors
- only one of --id or --prefix can be provided: %w
- %w: api key %d not found
- parsing machine key: %w
- failed to parse ApiKey
- failed to parse oauth client secret
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/d90d09147aa0d0f6.
Report an issue: GitHub.