kubernetes/kops · error

failed to find lifecycle hook %q: %w

Error message

failed to find lifecycle hook %q: %w

What it means

completeWarmingLifecycleAction describes the lifecycle hook named 'kops-warmpool' on the ASG '<instancegroup>.<clustername>'. If the DescribeLifecycleHooks API call itself errors (as opposed to returning zero hooks), nodeup wraps the AWS error with this message and the Run() call fails.

Source

Thrown at upup/pkg/fi/nodeup/command.go:440

		return "", fmt.Errorf("failed to get instance metadata type: %w", err)
	}
	defer result.Content.Close()
	instanceTypeName, err := io.ReadAll(result.Content)
	if err != nil {
		return "", fmt.Errorf("failed to read instance metadata response: %w", err)
	}
	return string(instanceTypeName), err
}

func completeWarmingLifecycleAction(ctx context.Context, cloud *awsup.Cloud, modelContext *model.NodeupModelContext) error {
	asgName := modelContext.BootConfig.InstanceGroupName + "." + modelContext.NodeupConfig.ClusterName
	hookName := "kops-warmpool"
	hooks, err := cloud.DescribeLifecycleHooks(ctx, &autoscaling.DescribeLifecycleHooksInput{
		AutoScalingGroupName: &asgName,
		LifecycleHookNames:   []string{hookName},
	})
	if err != nil {
		return fmt.Errorf("failed to find lifecycle hook %q: %w", hookName, err)
	}

	if len(hooks.LifecycleHooks) > 0 {
		klog.Info("Found ASG lifecycle hook")
		_, err := cloud.CompleteLifecycleAction(ctx, &autoscaling.CompleteLifecycleActionInput{
			AutoScalingGroupName:  &asgName,
			InstanceId:            &modelContext.InstanceID,
			LifecycleHookName:     &hookName,
			LifecycleActionResult: new("CONTINUE"),
		})
		if err != nil {
			return fmt.Errorf("failed to complete lifecycle hook %q for %q: %v", hookName, modelContext.InstanceID, err)
		}
		klog.Info("Lifecycle action completed")
	} else {
		klog.Info("No ASG lifecycle hook found")
	}
	return nil

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Grant the node instance role autoscaling:DescribeLifecycleHooks (scoped to the cluster ASGs if possible).
  2. Verify the ASG name <ig>.<cluster> exists in the node's region (aws autoscaling describe-auto-scaling-groups).
  3. Check the wrapped AWS error code: AuthorizationError -> permissions, ValidationError -> ASG name, Throttling -> backoff/retry.
  4. Ensure nodeup and cluster spec versions agree so hook/ASG naming conventions match.

Example fix

// before
// (no autoscaling:DescribeLifecycleHooks on node role)
// after
{"Effect":"Allow","Action":"autoscaling:DescribeLifecycleHooks","Resource":"*"}
Defensive patterns

Strategy: try-catch

Validate before calling

aws iam simulate-principal-policy --policy-source-arn <nodeRoleArn> --action-names autoscaling:DescribeLifecycleHooks --resource-arns '*'

Try / catch

hooks, err := cloud.DescribeLifecycleHooks(ctx, input)
if err != nil {
    var ae smithy.APIError
    if errors.As(err, &ae) {
        switch ae.ErrorCode() {
        case "AccessDenied": // fix IAM
        case "ValidationError": // wrong ASG name
        case "ThrottlingException": // backoff & retry
        }
    }
    return fmt.Errorf("failed to find lifecycle hook %q: %w", hookName, err)
}

Prevention

When it happens

Trigger: cloud.DescribeLifecycleHooks fails: IAM permission denied for autoscaling:DescribeLifecycleHooks, nonexistent/wrong ASG name, AWS API throttling, or regional/network failure.

Common situations: Node IAM role missing DescribeLifecycleHooks permission; instance group renamed so the ASG lookup name no longer matches; ASG is in a different region than the node's configured region; SDK throttling during large scale-ups.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/dfee51390abf07c7. Report an issue: GitHub.