{"record":{"id":"e42f6e9f79011fe7","repo":"juanfont/headscale","slug":"creating-preauth-key-w","errorCode":null,"errorMessage":"creating preauth key: %w","messagePattern":"creating preauth key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integration/helpers.go","lineNumber":1195,"sourceCode":"\t\tif err != nil {\n\t\t\treturn struct{}{}, fmt.Errorf(\"finding new client: %w\", err)\n\t\t}\n\n\t\treturn struct{}{}, nil\n\t}, backoff.WithBackOff(backoff.NewConstantBackOff(500*time.Millisecond)), backoff.WithMaxElapsedTime(10*time.Second))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"timeout waiting for new client: %w\", err)\n\t}\n\n\t// Get the user and create preauth key\n\tuser, err := GetUserByName(headscale, username)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting user: %w\", err)\n\t}\n\n\tauthKey, err := s.CreatePreAuthKey(mustParseID(user.Id), true, false)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating preauth key: %w\", err)\n\t}\n\n\t// Login the new client\n\terr = newClient.Login(headscale.GetEndpoint(), authKey.Key)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"logging in new client: %w\", err)\n\t}\n\n\treturn newClient, nil\n}\n\n// MustAddAndLoginClient is like [Scenario.AddAndLoginClient] but fails the test on error.\nfunc (s *Scenario) MustAddAndLoginClient(\n\tt *testing.T,\n\tusername string,\n\tversion string,\n\theadscale ControlServer,\n\ttsOpts ...tsic.Option,","sourceCodeStart":1177,"sourceCodeEnd":1213,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/integration/helpers.go#L1177-L1213","documentation":"Thrown when Scenario.CreatePreAuthKey(userID, reusable=true, ephemeral=false) fails while adding and logging in a client. This call exercises the headscale preauthkey gRPC endpoint; failure means the API rejected the create request (validation, database error) or the container exec/API transport failed.","triggerScenarios":"The preauthkey.Create RPC returns an error: invalid user ID from mustParseID, DB constraint failure, or expired/malformed auth for the admin API; alternatively the exec into the headscale container failed. Called with reusable=true and ephemeral=false in this path.","commonSituations":"Database backend issues (Postgres container not ready, SQLite locked); user record deleted between GetUserByName and this call; headscale binary in container crashing on the RPC.","solutions":["Check hs-*.stderr.log for the gRPC error returned by the preauthkey service","Confirm the user from GetUserByName still exists and its Id parses via mustParseID","If using Postgres, verify the postgres container is healthy (see error 668)","Re-run to rule out a transient DB lock on SQLite"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Verify user exists right before key creation\nuser, err := integration.GetUserByName(headscale, username)\nif err != nil { t.Fatal(err) }\n// mustParseID(user.Id) must succeed; guard it:\nif user.Id == \"\" { t.Fatal(\"empty user id\") }","typeGuard":null,"tryCatchPattern":"authKey, err := s.CreatePreAuthKey(mustParseID(user.Id), true, false)\nif err != nil {\n    t.Fatalf(\"preauth key creation failed; check DB backend health: %v\", err)\n}","preventionTips":["On Postgres runs, wait for the postgres container before creating keys","Check hs-*.stderr.log for the underlying gRPC status when this fires","Create keys only for users you just verified exist"],"tags":["integration-test","preauth-key","grpc-api"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}