{"record":{"id":"1acdf21be29b54c7","repo":"kubernetes/kops","slug":"failed-to-stop-server-q-w","errorCode":null,"errorMessage":"failed to stop server %q: %w","messagePattern":"failed to stop server %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/hetzner/cloud.go","lineNumber":270,"sourceCode":"\tserverID, err := strconv.ParseInt(instance.ID, 10, 64)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to convert server ID %q to int: %w\", instance.ID, err)\n\t}\n\n\terr = deleteServer(c, serverID)\n\n\treturn err\n}\n\n// deleteServer shuts down and deletes the given server\nfunc deleteServer(c *hetznerCloudImplementation, id int64) error {\n\tclient := c.ServerClient()\n\tctx := context.TODO()\n\n\tserver := &hcloud.Server{ID: id}\n\t_, _, err := client.Shutdown(ctx, server)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to stop server %q: %w\", strconv.FormatInt(id, 10), err)\n\t}\n\n\tfor i := 1; i <= 30; i++ {\n\t\tserver, _, err := client.GetByID(ctx, id)\n\t\tif err != nil || server == nil {\n\t\t\treturn fmt.Errorf(\"failed to get info for server %q: %w\", strconv.FormatInt(id, 10), err)\n\t\t}\n\n\t\tif server.Status == hcloud.ServerStatusOff {\n\t\t\tbreak\n\t\t}\n\n\t\ttime.Sleep(time.Second * 5)\n\t}\n\n\t_, err = client.Delete(ctx, server)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete server %q: %w\", strconv.FormatInt(id, 10), err)","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/hetzner/cloud.go#L252-L288","documentation":"deleteServer issues a graceful Shutdown via the Hetzner API before deletion; this error is thrown when the Shutdown call itself returns an error from the Hetzner Cloud API. The server is left running and deletion aborts.","triggerScenarios":"Calling DeleteInstance/DeleteGroup -> deleteServer when the server no longer exists (404 not_found), the API token lacks permission, the request times out, or the API is rate-limited/unavailable.","commonSituations":"Attempting to delete an already-removed server (e.g. manually deleted in Hetzner console or concurrent kOps run), token scope changes, or transient API failures during rolling updates.","solutions":["Check whether the server still exists (hcloud CLI / console); treat 404 as already deleted","Verify the API token has write permission on servers","Retry the deletion after transient errors; check for concurrent kOps processes","Inspect the wrapped hcloud error code for the precise cause"],"exampleFix":"// before\nif err != nil {\n\treturn fmt.Errorf(\"failed to stop server %q: %w\", strconv.FormatInt(id, 10), err)\n}\n// after\nif err != nil {\n\tif hcloud.IsError(err, hcloud.ErrorCodeNotFound) {\n\t\treturn nil // already deleted\n\t}\n\treturn fmt.Errorf(\"failed to stop server %q: %w\", strconv.FormatInt(id, 10), err)\n}","handlingStrategy":"retry","validationCode":"server, _, err := client.GetByID(ctx, id)\nif server == nil {\n\treturn nil // server already gone; skip shutdown/delete\n}","typeGuard":"func serverExists(client *hcloud.ServerClient, id int64) bool {\n\ts, _, err := client.GetByID(context.TODO(), id)\n\treturn err == nil && s != nil\n}","tryCatchPattern":"err := deleteServer(c, id)\nif err != nil {\n\tvar hErr *hcloud.Error\n\tif errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeNotFound {\n\t\treturn nil\n\t}\n\treturn err\n}","preventionTips":["Check server existence before shutdown/delete","Ensure the API token has server write scopes","Avoid concurrent kOps runs deleting the same instances","Retry transient 5xx errors with backoff"],"tags":["hetzner","api","server","shutdown"],"backgroundTag":"hetzner-api-request-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}