{"record":{"id":"14d66cb2ea580f25","repo":"juanfont/headscale","slug":"creating-preauth-key-with-options-w","errorCode":null,"errorMessage":"creating preauth key with options: %w","messagePattern":"creating preauth key with options: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integration/scenario.go","lineNumber":541,"sourceCode":") (*clientv1.PreAuthKey, error) {\n\tif headscale, err := s.Headscale(); err == nil { //nolint:noinlineerr\n\t\tkey, err := headscale.CreateAuthKey(user, reusable, ephemeral)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"creating user: %w\", err)\n\t\t}\n\n\t\treturn key, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"creating user: %w\", errNoHeadscaleAvailable)\n}\n\n// CreatePreAuthKeyWithOptions creates a \"pre authorised key\" with the specified options\n// to be created in the Headscale instance on behalf of the [Scenario].\nfunc (s *Scenario) CreatePreAuthKeyWithOptions(opts hsic.AuthKeyOptions) (*clientv1.PreAuthKey, error) {\n\theadscale, err := s.Headscale()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating preauth key with options: %w\", errNoHeadscaleAvailable)\n\t}\n\n\tkey, err := headscale.CreateAuthKeyWithOptions(opts)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating preauth key with options: %w\", err)\n\t}\n\n\treturn key, nil\n}\n\n// CreatePreAuthKeyWithTags creates a \"pre authorised key\" with the specified tags\n// to be created in the Headscale instance on behalf of the [Scenario].\nfunc (s *Scenario) CreatePreAuthKeyWithTags(\n\tuser uint64,\n\treusable bool,\n\tephemeral bool,\n\ttags []string,\n) (*clientv1.PreAuthKey, error) {","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/integration/scenario.go#L523-L559","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Print the wrapped gRPC error — it carries headscale's validation message (user not found, invalid tags, etc.)","Ensure the user exists and owns/has rights over any tags set in opts","Re-check AuthKeyOptions field values (expiration format, tags list) against hsic.AuthKeyOptions"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"key, err := scenario.CreatePreAuthKeyWithOptions(opts)\nif err != nil {\n    // wrapped gRPC status carries the server-side validation reason\n    t.Fatalf(\"CreatePreAuthKeyWithOptions: %v\", err)\n}","preventionTips":["Validate AuthKeyOptions fields (user, expiration, tags) before the call","Ensure tags are owned by the user in the test policy"],"tags":["preauth-key","grpc","integration-test","validation"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}