A 400 BadRequest error occurs when creating a GKE cluster with Terraform due to invalid network configuration, missing permissions, or incompatible cluster settings. This error typically indicates a configuration validation failure on the Google Cloud API side.
The BadRequest error (HTTP 400) returned by Google Cloud's API indicates that your Terraform configuration has invalid or conflicting parameters that Google Cloud cannot accept. This is different from authentication errors—your credentials are valid, but the cluster configuration itself violates GCP constraints or prerequisites. The error requires careful review of networking, service accounts, and cluster settings.
Ensure your network and subnetwork are properly configured. If using a custom VPC with custom-subnet mode, you must explicitly specify the subnetwork:
resource "google_container_cluster" "primary" {
name = "my-cluster"
location = "us-central1"
network = google_compute_network.vpc.name
subnetwork = google_compute_subnetwork.subnet.name
ip_allocation_policy {
cluster_secondary_range_name = "pods"
services_secondary_range_name = "services"
}
}Verify that the subnetwork exists in the specified network using:
gcloud compute networks subnets list --network=YOUR_NETWORK_NAMEIf creating a private cluster, you must enable Alias IP addresses. The error 'Alias IP addresses are required for private cluster' indicates this is missing:
resource "google_container_cluster" "primary" {
name = "my-cluster"
location = "us-central1"
private_cluster_config {
enable_private_nodes = true
enable_private_endpoint = true
master_ipv4_cidr_block = "172.16.0.0/28"
}
ip_allocation_policy {
cluster_secondary_range_name = "pods"
services_secondary_range_name = "services"
}
}Ensure secondary IP ranges for pods and services exist in your subnetwork.
If you get 'The user does not have access to service account', ensure the service account exists and you have the iam.serviceAccountUser role. Either use a service account you have permissions for:
resource "google_container_cluster" "primary" {
name = "my-cluster"
location = "us-central1"
node_config {
service_account = google_service_account.custom_sa.email
oauth_scopes = [
"https://www.googleapis.com/auth/cloud-platform",
]
}
}Or verify your default service account:
gcloud iam service-accounts describe [email protected]If creating a node pool fails with 'Applying kubernetes label is not allowed', remove reserved Kubernetes label prefixes during cluster creation:
resource "google_container_node_pool" "primary_nodes" {
name = "primary-node-pool"
cluster = google_container_cluster.primary.id
node_count = 3
node_config {
# Do NOT use app.kubernetes.io/* labels here
labels = {
environment = "production"
team = "platform"
}
}
}Apply reserved labels (app.kubernetes.io/*) after cluster creation using kubectl instead.
The error 'Can only enable serverless at cluster creation time' means Cloud Run must be enabled during initial cluster creation, not after. If you need Cloud Run, add it upfront:
resource "google_container_cluster" "primary" {
name = "my-cluster"
location = "us-central1"
addons_config {
cloudrun_config {
disabled = false
}
}
}Note: Once enabled, Cloud Run can be disabled, but cannot be re-enabled without recreating the cluster.
If creating Windows node pools, disable Workload Identity which is not supported on Windows:
resource "google_container_node_pool" "windows_nodes" {
name = "windows-pool"
cluster = google_container_cluster.primary.id
node_config {
machine_type = "n1-standard-2"
image_type = "WINDOWS_SAC"
workload_metadata_config {
mode = "GCE_METADATA"
}
}
}This sets metadata to GCE only, disabling Workload Identity on Windows nodes.
BadRequest errors require examining the specific error message returned by Google Cloud's API—different messages indicate different root causes. Use terraform plan -out=plan.tfplan and terraform apply plan.tfplan to see the full error details. For persistent issues, enable debug logging: TF_LOG=DEBUG terraform apply to see API requests and responses. Google Cloud's quota and billing account status can also cause BadRequest errors; verify these in the GCP Console before debugging configuration.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform
Error: Error rendering template: template not found
How to fix "template not found" error in Terraform