juanfont/headscale · error

creating preauth key with options: %w

Error message

creating preauth key with options: %w

What it means

Returned by Scenario.CreatePreAuthKeyWithOptions when hsic's CreateAuthKeyWithOptions call fails against the headscale gRPC API. The options struct (AuthKeyOptions) is serialized into a CreatePreAuthKey gRPC request; server-side validation failures surface here.

Source

Thrown at integration/scenario.go:541

) (*clientv1.PreAuthKey, error) {
	if headscale, err := s.Headscale(); err == nil { //nolint:noinlineerr
		key, err := headscale.CreateAuthKey(user, reusable, ephemeral)
		if err != nil {
			return nil, fmt.Errorf("creating user: %w", err)
		}

		return key, nil
	}

	return nil, fmt.Errorf("creating user: %w", errNoHeadscaleAvailable)
}

// CreatePreAuthKeyWithOptions creates a "pre authorised key" with the specified options
// to be created in the Headscale instance on behalf of the [Scenario].
func (s *Scenario) CreatePreAuthKeyWithOptions(opts hsic.AuthKeyOptions) (*clientv1.PreAuthKey, error) {
	headscale, err := s.Headscale()
	if err != nil {
		return nil, fmt.Errorf("creating preauth key with options: %w", errNoHeadscaleAvailable)
	}

	key, err := headscale.CreateAuthKeyWithOptions(opts)
	if err != nil {
		return nil, fmt.Errorf("creating preauth key with options: %w", err)
	}

	return key, nil
}

// CreatePreAuthKeyWithTags creates a "pre authorised key" with the specified tags
// to be created in the Headscale instance on behalf of the [Scenario].
func (s *Scenario) CreatePreAuthKeyWithTags(
	user uint64,
	reusable bool,
	ephemeral bool,
	tags []string,
) (*clientv1.PreAuthKey, error) {

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Print the wrapped gRPC error — it carries headscale's validation message (user not found, invalid tags, etc.)
  2. Ensure the user exists and owns/has rights over any tags set in opts
  3. Re-check AuthKeyOptions field values (expiration format, tags list) against hsic.AuthKeyOptions
Defensive patterns

Strategy: try-catch

Try / catch

key, err := scenario.CreatePreAuthKeyWithOptions(opts)
if err != nil {
    // wrapped gRPC status carries the server-side validation reason
    t.Fatalf("CreatePreAuthKeyWithOptions: %v", err)
}

Prevention

When it happens

Trigger: Calling s.CreatePreAuthKeyWithOptions(opts) with a non-existent user ID, invalid expiration, or tags the user does not own; the gRPC call itself fails (connection/auth).

Common situations: AuthKeyOptions.Reusable/Ephemeral/Tags combination rejected by headscale policy (e.g. tags not pre-authorized for the user); user ID stale after user recreation; malformed expiration time.

Related errors


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/14d66cb2ea580f25. Report an issue: GitHub.