hashicorp/terraform · error
impersonate_service_account_delegates elements must not be n
Error message
impersonate_service_account_delegates elements must not be null
What it means
This error is emitted by the GCS backend's Configure() while iterating over the 'impersonate_service_account_delegates' list. Terraform walks each element of that list and rejects any element that is a null cty.Value, because the impersonation API needs a concrete service-account email string for every hop in the delegation chain. A null element would later cause google.golang.org/api/impersonate to fail with a less helpful message, so the backend validates eagerly.
Source
Thrown at internal/backend/remote-state/gcs/backend.go:223
)
}
credOptions = append(credOptions, option.WithCredentialsJSON([]byte(contents)))
}
// Service Account Impersonation
if v := data.String("impersonate_service_account"); v != "" {
ServiceAccount := v
var delegates []string
delegatesVal := data.GetAttr("impersonate_service_account_delegates", cty.List(cty.String))
if !delegatesVal.IsNull() && delegatesVal.LengthInt() != 0 {
delegates = make([]string, 0, delegatesVal.LengthInt())
for it := delegatesVal.ElementIterator(); it.Next(); {
_, v := it.Element()
if v.IsNull() {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("impersonate_service_account_delegates elements must not be null"),
)
}
delegates = append(delegates, v.AsString())
}
}
ts, err := impersonate.CredentialsTokenSource(ctx, impersonate.CredentialsConfig{
TargetPrincipal: ServiceAccount,
Scopes: []string{storage.ScopeReadWrite},
Delegates: delegates,
}, credOptions...)
if err != nil {
return backendbase.ErrorAsDiagnostics(err)
}
opts = append(opts, option.WithTokenSource(ts))
View on GitHub (pinned to c9def3e214)
Solutions
- Open the backend block and inspect every entry of impersonate_service_account_delegates; remove or replace any null element with a full service-account delegate email like 'projects/-/serviceAccounts/SA_NAME@PROJECT.iam.gserviceaccount.com'.
- If the list is built from variables, give each variable a concrete non-null default or guard it with a coalesce() so the value is never null at plan/init time.
- Run 'terraform init -backend=false' to confirm the config parses, then fix the offending element and re-run 'terraform init'.
Example fix
// before
impersonate_service_account = "deployer@proj.iam.gserviceaccount.com"
impersonate_service_account_delegates = [var.delegate] // var.delegate defaults to null
// after
variable "delegate" { default = "projects/-/serviceAccounts/originator@proj.iam.gserviceaccount.com" }
impersonate_service_account = "deployer@proj.iam.gserviceaccount.com"
impersonate_service_account_delegates = [var.delegate] Defensive patterns
Strategy: validation
Validate before calling
// Validate before passing to the backend
func validateDelegates(del cty.Value) error {
if del.IsNull() { return nil }
for it := del.ElementIterator(); it.Next(); {
_, v := it.Element()
if v.IsNull() {
return fmt.Errorf("impersonate_service_account_delegates contains a null element")
}
}
return nil
} Type guard
// Terraform HCL: never produce null via coalesce // impersonate_service_account_delegates = [coalesce(var.delegate, "projects/-/serviceAccounts/fallback@proj.iam.gserviceaccount.com")]
Prevention
- Give every variable feeding impersonate_service_account_delegates a concrete non-null default.
- Lint the backend block with terraform validate before init.
- Avoid [var.x] patterns unless var.x is guaranteed non-null.
When it happens
Trigger: Set 'impersonate_service_account' to a non-empty string AND 'impersonate_service_account_delegates' to a list containing a null element (e.g. [null], ["projects/-/serviceAccounts/a@x.iam.gserviceaccount.com", null]). Triggered during terraform init when the backend block is configured in this way.
Common situations: HCL authored with an unknown/variable placeholder that resolves to null (e.g. impersonate_service_account_delegates = [var.delegate] where var.delegate has no default), or a list literal typo, or generated config from tfvars that left a slot empty.
Related errors
- storage.NewClient() failed: %v
- Error loading encryption key: %s
- Error decoding encryption key: %s
- cowardly refusing to delete the %q state
- %q is not a valid state name
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/f21976b0db780e41.
Report an issue: GitHub.