{"record":{"id":"65af2a4e8068ccc9","repo":"hashicorp/terraform","slug":"secret-suffix-must-not-end-with-number-got","errorCode":null,"errorMessage":"secret_suffix must not end with '-<number>', got %q","messagePattern":"secret_suffix must not end with '-<number>', got %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/kubernetes/backend.go","lineNumber":334,"sourceCode":"\t\t\tkV, vV := it.Element()\n\t\t\tif vV.IsNull() {\n\t\t\t\tvV = cty.StringVal(\"\")\n\t\t\t}\n\t\t\tlabels[kV.AsString()] = vV.AsString()\n\t\t}\n\t\tb.labels = labels\n\t}\n\n\tns := data.String(\"namespace\")\n\tb.namespace = ns\n\n\tb.nameSuffix = data.String(\"secret_suffix\")\n\tif hasNumericSuffix(b.nameSuffix, \"-\") {\n\t\t// If the last segment is a number, it's considered invalid.\n\t\t// The backend automatically appends its own numeric suffix when chunking large state files into multiple secrets.\n\t\t// Allowing a user-defined numeric suffix could cause conflicts with this mechanism.\n\t\treturn backendbase.ErrorAsDiagnostics(\n\t\t\tfmt.Errorf(\"secret_suffix must not end with '-<number>', got %q\", b.nameSuffix),\n\t\t)\n\t}\n\n\tb.config = cfg\n\n\treturn nil\n}\n\nfunc getInitialConfig(data backendbase.SDKLikeData) (*restclient.Config, error) {\n\tvar cfg *restclient.Config\n\tvar err error\n\n\tinCluster := data.Bool(\"in_cluster_config\")\n\tif inCluster {\n\t\tcfg, err = restclient.InClusterConfig()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/kubernetes/backend.go#L316-L352","documentation":"The Kubernetes backend validates that secret_suffix does not end with a hyphen followed by a number. The backend appends its own `-part-<N>` numeric index when chunking large state files across multiple secrets, so a user suffix like 'foo-2' would collide with that scheme and corrupt state retrieval. Configure() rejects such suffixes up front via hasNumericSuffix.","triggerScenarios":"Configuring the kubernetes backend with a secret_suffix whose final '-segment' parses as an integer (e.g. 'app-3', 'prod-blue-1'), causing hasNumericSuffix to return true at backend.go:329 and fail configuration.","commonSituations":"Auto-generated suffixes that include a version or index (e.g. 'tfstate-${env}-${build_number}'); a refactor that appended '-1' to disambiguate; copy-paste from a naming scheme that ends in a number.","solutions":["Choose a secret_suffix whose last hyphen-separated segment is non-numeric (e.g. 'app-prod' instead of 'app-1').","Move any numeric component earlier in the suffix so the final segment is textual.","Regenerate any templated suffix to guarantee an alphabetic final segment."],"exampleFix":"# before - suffix ends in a number, collides with chunk indexing\nsecret_suffix = \"myapp-${var.env}-1\"\n\n# after - final segment is non-numeric\nsecret_suffix = \"myapp-${var.env}-state\"","handlingStrategy":"validation","validationCode":"// Validate secret_suffix shape before configuring the backend\nfunc validSecretSuffix(s string) bool {\n    parts := strings.Split(s, \"-\")\n    if _, err := strconv.Atoi(parts[len(parts)-1]); err == nil {\n        return false // last segment is numeric -> rejected\n    }\n    return true\n}","typeGuard":"func isValidK8sSecretSuffix(s string) bool {\n    if s == \"\" { return false }\n    parts := strings.Split(s, \"-\")\n    if _, err := strconv.Atoi(parts[len(parts)-1]); err == nil {\n        return false\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["End secret_suffix with an alphabetic segment (e.g. -state, -tf).","Avoid injecting build/version numbers at the tail of the suffix.","Add a policy/template check on generated suffixes before terraform init."],"tags":["kubernetes","remote-state","validation","config","terraform-backend"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}