netbirdio/netbird · warning

tokenID is required

Error message

tokenID is required

What it means

Client-side guard in ReverseProxyTokensAPI.Delete against an empty proxy token ID. An empty ID would make url.PathEscape("") collapse the DELETE URL onto the collection endpoint /api/reverse-proxies/proxy-tokens, deleting nothing or hitting the wrong route. The guard rejects the call before any request is issued.

Source

Thrown at shared/management/client/rest/reverse_proxy_tokens.go:69

		defer resp.Body.Close()
	}
	ret, err := parseResponse[api.ProxyTokenCreated](resp)
	if err != nil {
		return nil, err
	}
	return &ret, nil
}

// Delete revokes a previously-issued proxy token by ID. Revoked tokens
// remain in List output (with revoked=true) so operators can audit which
// credentials existed; the plain secret can no longer authenticate any
// new proxy registration.
func (a *ReverseProxyTokensAPI) Delete(ctx context.Context, tokenID string) error {
	// Guard against the empty input: url.PathEscape("") returns "" which
	// would collapse the request URL onto the collection endpoint and
	// silently delete nothing (or 405 depending on routing).
	if tokenID == "" {
		return errors.New("tokenID is required")
	}
	resp, err := a.c.NewRequest(ctx, "DELETE", "/api/reverse-proxies/proxy-tokens/"+url.PathEscape(tokenID), nil, nil)
	if err != nil {
		return err
	}
	if resp.Body != nil {
		defer resp.Body.Close()
	}
	return nil
}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Use the token ID exactly as returned by the Create/List endpoints
  2. Validate the ID is non-empty before invoking Delete
  3. Log and skip empty IDs when iterating a list of tokens to revoke

Example fix

// before
err := restClient.ReverseProxyTokens.Delete(ctx, tokenID)

// after
if tokenID == "" {
	return fmt.Errorf("tokenID is required to revoke a proxy token")
}
err := restClient.ReverseProxyTokens.Delete(ctx, tokenID)
Defensive patterns

Strategy: validation

Validate before calling

if tokenID == "" {
	return fmt.Errorf("tokenID is required before revoking a proxy token")
}
err := restClient.ReverseProxyTokens.Delete(ctx, tokenID)

Try / catch

if err := restClient.ReverseProxyTokens.Delete(ctx, tokenID); err != nil {
	if err.Error() == "tokenID is required" {
		// the ID lookup upstream produced nothing; fix the source of tokenID
	}
	return err
}

Prevention

When it happens

Trigger: Calling Delete(ctx, "") with a token ID variable that was never populated, e.g. an unset env var, a zero-value struct field, or a lookup that returned no ID.

Common situations: Revocation scripts iterating tokens parsed from stale output; config keys for the token ID omitted; copy-paste helper calls missing the argument.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/235a8c181f68857f. Report an issue: GitHub.