kubernetes/kops · error

modifying NLB target group health check

Error message

modifying NLB target group health check: %w

What it means

After creating the target group, RenderAWS issues ModifyTargetGroup to configure health check settings (path, matcher, interval, timeout, healthy/unhealthy thresholds). This wraps any error from that API call. The group exists, but its health check configuration could not be applied.

Solutions

  1. Fix the health check values in the load balancer spec (path must start with /, timeout < interval, thresholds within AWS limits)
  2. Verify IAM permission elasticloadbalancing:ModifyTargetGroup
  3. Re-run the apply if the cause was a transient AWS error or a concurrent modification
Defensive patterns

Strategy: validation

Validate before calling

// validate health check params before apply
if proto == "HTTP" || proto == "HTTPS" {
  if !strings.HasPrefix(path, "/") { return errors.New("HealthCheckPath must start with /") }
  if timeout >= interval { return errors.New("health check timeout must be < interval") }
}

Try / catch

if err := applyCluster(); err != nil && strings.Contains(err.Error(), "modifying NLB target group health check") {
  return fmt.Errorf("check HealthCheckPath/Matcher/timeout values in spec: %w", err)
}

Prevention

When it happens

Trigger: HTTP/HTTPS protocol target groups where setting HealthCheckPath or HttpCode matcher "200-399" is rejected, or any ELBV2 ModifyTargetGroup API error (throttling, permission, target group concurrently deleted).

Common situations: Invalid health check parameters (bad path, timeout > interval, thresholds out of range) in the cluster spec; IAM missing elasticloadbalancing:ModifyTargetGroup; concurrent apply/deletion racing the modify call.

Related errors


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

Appendix: source

Thrown at upup/pkg/fi/cloudup/awstasks/targetgroup.go:412

			}
			// Health check settings are only applied on create, so reconcile them here for an existing target group.
			if changes.HealthCheckProtocol != "" || changes.HealthCheckPath != nil ||
				changes.HealthyThreshold != nil || changes.UnhealthyThreshold != nil {
				klog.V(2).Infof("Modifying Target Group health check for NLB")
				proto := e.HealthCheckProtocol
				request := &elbv2.ModifyTargetGroupInput{
					TargetGroupArn:          a.ARN,
					HealthCheckProtocol:     proto,
					HealthyThresholdCount:   e.HealthyThreshold,
					UnhealthyThresholdCount: e.UnhealthyThreshold,
				}
				// HTTP/HTTPS health checks need a path and matcher, 200-399 matches the NLB create default.
				if proto == elbv2types.ProtocolEnumHttp || proto == elbv2types.ProtocolEnumHttps {
					request.HealthCheckPath = e.HealthCheckPath
					request.Matcher = &elbv2types.Matcher{HttpCode: new("200-399")}
				}
				if _, err := t.Cloud.ELBV2().ModifyTargetGroup(ctx, request); err != nil {
					return fmt.Errorf("modifying NLB target group health check: %w", err)
				}
			}
		}
	}
	return nil
}

func ModifyTargetGroupAttributes(ctx context.Context, cloud awsup.AWSCloud, arn *string, attributes map[string]string) error {
	klog.V(2).Infof("Modifying Target Group attributes for NLB")
	attrReq := &elbv2.ModifyTargetGroupAttributesInput{
		Attributes:     []elbv2types.TargetGroupAttribute{},
		TargetGroupArn: arn,
	}
	for k, v := range attributes {
		attrReq.Attributes = append(attrReq.Attributes, elbv2types.TargetGroupAttribute{
			Key:   new(k),
			Value: new(v),
		})

View on GitHub (pinned to 4c8573c808)