kubernetes/kops · error

AttachDetachReconcileSyncPeriod cannot be set to less than 1

Error message

AttachDetachReconcileSyncPeriod cannot be set to less than 1 second

What it means

BuildOptions in the KubeControllerManager component builder validates the AttachDetachReconcileSyncPeriod configured on the cluster spec. The kube-controller-manager itself refuses sub-second values for this flag, so kOps pre-emptively rejects anything under 1 second with this error to fail fast at cluster-spec validation time instead of at controller-manager startup.

Source

Thrown at pkg/model/components/kubecontrollermanager.go:73

	{
		klog.V(4).Infof("Kubernetes version %q supports AttachDetachReconcileSyncPeriod; will configure", b.ControlPlaneKubernetesVersion().String())
		// If not set ... or set to 0s ... which is stupid
		if kcm.AttachDetachReconcileSyncPeriod == nil ||
			kcm.AttachDetachReconcileSyncPeriod.Duration.String() == "0s" {

			klog.V(8).Infof("AttachDetachReconcileSyncPeriod is not set; will set to default %v", defaultAttachDetachReconcileSyncPeriod)
			kcm.AttachDetachReconcileSyncPeriod = &metav1.Duration{Duration: defaultAttachDetachReconcileSyncPeriod}

			// If less than 1 min and greater than 1 sec ... you get a warning
		} else if kcm.AttachDetachReconcileSyncPeriod.Duration < defaultAttachDetachReconcileSyncPeriod &&
			kcm.AttachDetachReconcileSyncPeriod.Duration > time.Second {

			klog.Infof("KubeControllerManager AttachDetachReconcileSyncPeriod is set lower than recommended: %s", defaultAttachDetachReconcileSyncPeriod)

			// If less than 1sec you get an error.  Controller is coded to not allow configuration
			// less than one second.
		} else if kcm.AttachDetachReconcileSyncPeriod.Duration < time.Second {
			return fmt.Errorf("AttachDetachReconcileSyncPeriod cannot be set to less than 1 second")
		}
	}

	kcm.ClusterName = b.ClusterName
	kcm.CloudProvider = "external"

	if kcm.LogLevel == 0 {
		kcm.LogLevel = 2
	}

	image, err := Image("kube-controller-manager", clusterSpec, b.AssetBuilder)
	if err != nil {
		return err
	}
	kcm.Image = image

	// Doesn't seem to be any real downside to always doing a leader election
	kcm.LeaderElection = &kops.LeaderElectionConfiguration{LeaderElect: new(true)}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set attachDetachReconcileSyncPeriod to at least 1s in cluster.spec.kubeControllerManager
  2. Remove the field entirely to fall back to the kOps default (defaultAttachDetachReconcileSyncPeriod)
  3. If faster reconciliation is needed, note the controller-manager hard-codes a 1s minimum, so choose 1s and tune other knobs instead

Example fix

// before
spec:
  kubeControllerManager:
    attachDetachReconcileSyncPeriod: 500ms
// after
spec:
  kubeControllerManager:
    attachDetachReconcileSyncPeriod: 1s
Defensive patterns

Strategy: validation

Validate before calling

d, err := time.ParseDuration(cluster.Spec.KubeControllerManager.AttachDetachReconcileSyncPeriod.Duration.String())
if err != nil {
    return fmt.Errorf("invalid attachDetachReconcileSyncPeriod: %w", err)
}
if d < time.Second {
    return fmt.Errorf("attachDetachReconcileSyncPeriod must be >= 1s, got %s", d)
}

Try / catch

if err := builder.BuildOptions(cluster); err != nil {
    if strings.Contains(err.Error(), "AttachDetachReconcileSyncPeriod cannot be set to less than 1 second") {
        cluster.Spec.KubeControllerManager.AttachDetachReconcileSyncPeriod = metav1.Duration{Duration: time.Second}
        err = builder.BuildOptions(cluster)
    }
    return err
}

Prevention

When it happens

Trigger: Setting cluster.spec.kubeControllerManager.attachDetachReconcileSyncPeriod to a duration below time.Second (e.g. "500ms", "0s") and then calling BuildOptions via the KCM builder, as exercised by Test_Build_KCM_Builder and Test_Build_KCM_Builder_Change_Duration.

Common situations: Operators tuning volume attach/detach reconciliation speed for stateful workloads copy a sub-second value from a blog or upstream flag docs; copying a k8s upstream flag default that is expressed in milliseconds; accidentally writing "0" meaning 'default' when the code interprets it as 0s.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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