{"record":{"id":"222a92e599023867","repo":"k3s-io/k3s","slug":"unknown-stage-s-requested","errorCode":null,"errorMessage":"unknown stage %s requested","messagePattern":"unknown stage (.+?) requested","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"pkg/server/handlers/secrets-encrypt.go","lineNumber":223,"sourceCode":"\t\t}\n\n\t\tencryptReq, err := getEncryptionRequest(req)\n\t\tif err != nil {\n\t\t\tutil.SendError(err, resp, req, http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t\tif encryptReq.Stage != nil {\n\t\t\tswitch *encryptReq.Stage {\n\t\t\tcase secretsencrypt.EncryptionPrepare:\n\t\t\t\terr = encryptionPrepare(ctx, control, encryptReq.Force)\n\t\t\tcase secretsencrypt.EncryptionRotate:\n\t\t\t\terr = encryptionRotate(ctx, control, encryptReq.Force)\n\t\t\tcase secretsencrypt.EncryptionRotateKeys:\n\t\t\t\terr = encryptionRotateKeys(ctx, control)\n\t\t\tcase secretsencrypt.EncryptionReencryptActive:\n\t\t\t\terr = encryptionReencrypt(ctx, control, encryptReq.Force, encryptReq.Skip)\n\t\t\tdefault:\n\t\t\t\terr = fmt.Errorf(\"unknown stage %s requested\", *encryptReq.Stage)\n\t\t\t}\n\t\t} else if encryptReq.Enable != nil {\n\t\t\terr = encryptionEnable(ctx, control, *encryptReq.Enable)\n\t\t}\n\n\t\tif err != nil {\n\t\t\tutil.SendErrorWithID(err, \"secret-encrypt\", resp, req, http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t\t// If a user kills the k3s server immediately after this call, we run into issues where the files\n\t\t// have not yet been written. This sleep ensures that things have time to sync to disk before\n\t\t// the request completes.\n\t\ttime.Sleep(1 * time.Second)\n\t\tresp.WriteHeader(http.StatusOK)\n\t})\n}\n\nfunc encryptionPrepare(ctx context.Context, control *config.Control, force bool) error {","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/server/handlers/secrets-encrypt.go#L205-L241","documentation":"The secrets-encrypt API dispatches on the 'stage' field of the request and only accepts prepare, rotate, rotate-keys, and re-encrypt-active. Any other stage string falls through the switch and is rejected with this message as HTTP 400 (error id 'secret-encrypt'). It is purely request-validation, not a cluster state problem.","triggerScenarios":"POST to the secrets-encrypt handler with stage set to a typo or unsupported value: 'prepared', 'rotate-keys ' (whitespace), 'reencrypt', 're-encrypt', or an internal stage name from a different k3s version. Usually reached by calling the HTTP API directly or via a mismatched k3s CLI talking to a newer/older server.","commonSituations":"Custom automation hitting the endpoint with hand-built JSON; CLI/server version skew where the CLI sends a stage name the server build does not know; copy-paste stage names from documentation of another version.","solutions":["Use one of the four exact stage tokens: prepare, rotate, rotate-keys, re-encrypt-active.","Check version skew: ensure the k3s CLI and server are the same release so stage vocabularies match.","Trim/validate the stage string in your automation before sending (no whitespace, exact case).","For enable/disable semantics, omit stage and set the enable boolean instead."],"exampleFix":"# before\ncurl -sk -X POST $SERVER/v1-k3s/secrets-encrypt -d '{\"stage\":\"reencrypt\"}'\n\n# after\ncurl -sk -X POST $SERVER/v1-k3s/secrets-encrypt -d '{\"stage\":\"re-encrypt-active\"}'","handlingStrategy":"validation","validationCode":"var validStages = map[string]bool{\"prepare\":true,\"rotate\":true,\"rotate-keys\":true,\"re-encrypt-active\":true}\nif req.Stage != nil && !validStages[*req.Stage] {\n    http.Error(w, \"stage must be one of prepare|rotate|rotate-keys|re-encrypt-active\", 400)\n}","typeGuard":"func isValidStage(s string) bool {\n    switch s {\n    case \"prepare\", \"rotate\", \"rotate-keys\", \"re-encrypt-active\":\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Use the k3s CLI rather than raw HTTP for stage requests","Keep CLI and server versions in lockstep","Treat HTTP 400 with id 'secret-encrypt' as a request bug, not cluster state"],"tags":["api","validation","secrets-encryption"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}