kubernetes/kops · error

direct configuration not supported with CloudProvider:%q

Error message

direct configuration not supported with CloudProvider:%q

What it means

When c.Target is TargetDirect (applying changes directly to a cloud API), Run selects the concrete APITarget via a switch over CloudProvider; a provider without a direct-apply target implementation hits default and returns 'direct configuration not supported'. Direct apply exists for known providers only — some providers only support terraform output.

Source

Thrown at upup/pkg/fi/cloudup/apply_cluster.go:769

			target = gce.NewGCEAPITarget(cloud.(gce.GCECloud))
		case kops.CloudProviderAWS:
			target = awsup.NewAWSAPITarget(cloud.(awsup.AWSCloud))
		case kops.CloudProviderDO:
			target = do.NewDOAPITarget(cloud.(do.DOCloud))
		case kops.CloudProviderHetzner:
			target = hetzner.NewHetznerAPITarget(cloud.(hetzner.HetznerCloud))
		case kops.CloudProviderOpenstack:
			target = openstack.NewOpenstackAPITarget(cloud.(openstack.OpenstackCloud))
		case kops.CloudProviderAzure:
			target = azure.NewAzureAPITarget(cloud.(azure.AzureCloud))
		case kops.CloudProviderScaleway:
			target = scaleway.NewScwAPITarget(cloud.(scaleway.ScwCloud))
		case kops.CloudProviderLinode:
			target = linode.NewAPITarget(cloud.(linode.LinodeCloud))
		case kops.CloudProviderMetal:
			target = metal.NewAPITarget(cloud.(*metal.Cloud), nil)
		default:
			return nil, fmt.Errorf("direct configuration not supported with CloudProvider:%q", cluster.GetCloudProvider())
		}

	case TargetTerraform:
		outDir := c.OutDir
		tf := terraform.NewTerraformTarget(cloud, project, outDir, cluster.Spec.Target)

		// Register an azurerm provider alias for state storage blobs.
		// If the storage account is in a different subscription, pass subscription_id.
		if azureSpec := cluster.Spec.CloudProvider.Azure; azureSpec != nil {
			args := map[string]string{}
			if azureSpec.StorageAccountID != "" {
				storageAccountID, err := arm.ParseResourceID(azureSpec.StorageAccountID)
				if err != nil {
					return nil, fmt.Errorf("parsing StorageAccountID: %w", err)
				}
				if storageAccountID.SubscriptionID != azureSpec.SubscriptionID {
					args["subscription_id"] = storageAccountID.SubscriptionID
				}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Use terraform output instead: `kops update cluster --target=terraform` and apply the generated tf files
  2. Use a provider that supports direct apply (aws, gce, etc.) for direct configuration
  3. If implementing a provider, add a NewAPITarget case to the TargetDirect switch

Example fix

// before
kops update cluster --name x  # direct apply
// after
kops update cluster --name x --target=terraform
cd out/terraform && terraform plan
Defensive patterns

Strategy: validation

Validate before calling

[ "$CLOUD" = aws ] || [ "$CLOUD" = gce ] || echo "direct apply may be unsupported for $CLOUD; use --target=terraform"

Try / catch

if err := updateCluster(); err != nil { if strings.Contains(err.Error(), "direct configuration not supported") { return fmt.Errorf("use --target=terraform for this provider: %w", err) } return err }

Prevention

When it happens

Trigger: Running `kops update cluster` without --target=terraform (i.e. direct apply) on a provider whose case is absent from the TargetDirect switch in apply_cluster.go.

Common situations: Using a newly added/alpha provider (or fork provider) that only supports generating terraform, assuming direct apply works; running `kops apply` style flows against unsupported clouds.

Related errors


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