{"record":{"id":"f21976b0db780e41","repo":"hashicorp/terraform","slug":"impersonate-service-account-delegates-elements-mus","errorCode":null,"errorMessage":"impersonate_service_account_delegates elements must not be null","messagePattern":"impersonate_service_account_delegates elements must not be null","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/gcs/backend.go","lineNumber":223,"sourceCode":"\t\t\t)\n\t\t}\n\n\t\tcredOptions = append(credOptions, option.WithCredentialsJSON([]byte(contents)))\n\t}\n\n\t// Service Account Impersonation\n\tif v := data.String(\"impersonate_service_account\"); v != \"\" {\n\t\tServiceAccount := v\n\t\tvar delegates []string\n\n\t\tdelegatesVal := data.GetAttr(\"impersonate_service_account_delegates\", cty.List(cty.String))\n\t\tif !delegatesVal.IsNull() && delegatesVal.LengthInt() != 0 {\n\t\t\tdelegates = make([]string, 0, delegatesVal.LengthInt())\n\t\t\tfor it := delegatesVal.ElementIterator(); it.Next(); {\n\t\t\t\t_, v := it.Element()\n\t\t\t\tif v.IsNull() {\n\t\t\t\t\treturn backendbase.ErrorAsDiagnostics(\n\t\t\t\t\t\tfmt.Errorf(\"impersonate_service_account_delegates elements must not be null\"),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tdelegates = append(delegates, v.AsString())\n\t\t\t}\n\t\t}\n\n\t\tts, err := impersonate.CredentialsTokenSource(ctx, impersonate.CredentialsConfig{\n\t\t\tTargetPrincipal: ServiceAccount,\n\t\t\tScopes:          []string{storage.ScopeReadWrite},\n\t\t\tDelegates:       delegates,\n\t\t}, credOptions...)\n\n\t\tif err != nil {\n\t\t\treturn backendbase.ErrorAsDiagnostics(err)\n\t\t}\n\n\t\topts = append(opts, option.WithTokenSource(ts))\n","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/gcs/backend.go#L205-L241","documentation":"Thrown while building the service-account impersonation token source when the impersonate_service_account_delegates list contains a null element. The backend iterates the cty list and rejects any null entry before forwarding the delegates to impersonate.CredentialsTokenSource.","triggerScenarios":"Configure is called with impersonate_service_account set AND impersonate_service_account_delegates as a non-empty list in which at least one element is cty.NullVal(cty.String).","commonSituations":"A templated backend block renders a delegate from a variable that is sometimes null; a list like [\"acct@...\", null] is built via compact() that failed to drop nulls; YAML-to-HCL conversion emits explicit nulls.","solutions":["Remove null entries from the impersonate_service_account_delegates list.","If delegates come from a variable, filter them: use a local with [for d in var.delegates : d if d != null].","Leave impersonate_service_account_delegates unset entirely if you have no delegate chain."],"exampleFix":"// before\nbackend \"gcs\" {\n  bucket                       = \"tf-state\"\n  impersonate_service_account  = \"sa@proj.iam.gserviceaccount.com\"\n  impersonate_service_account_delegates = [\"delegate@...\", null]\n}\n// after\nbackend \"gcs\" {\n  bucket                       = \"tf-state\"\n  impersonate_service_account  = \"sa@proj.iam.gserviceaccount.com\"\n  impersonate_service_account_delegates = [\"delegate@...\"]\n}","handlingStrategy":"validation","validationCode":"// Filter null delegates before passing to the backend config.\ndelegates := []string{}\nfor _, d := range rawDelegates {\n    if d == nil || d == cty.NullVal(cty.String) { continue }\n    delegates = append(delegates, d.AsString())\n}","typeGuard":"func hasNullElement(listVal cty.Value) bool {\n    if listVal.IsNull() || listVal.LengthInt() == 0 { return false }\n    for it := listVal.ElementIterator(); it.Next(); {\n        _, v := it.Element()\n        if v.IsNull() { return true }\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Use Terraform locals to filter nulls: `locals { delegates = [for d in var.delegates : d if d != null] }`.","Avoid templating delegate lists from sources that emit explicit nulls."],"tags":["gcs","backend","impersonation","configuration","iam"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}