hashicorp/terraform · error
secret_suffix must not end with '-<number>', got %q
Error message
secret_suffix must not end with '-<number>', got %q
What it means
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.
Source
Thrown at internal/backend/remote-state/kubernetes/backend.go:334
kV, vV := it.Element()
if vV.IsNull() {
vV = cty.StringVal("")
}
labels[kV.AsString()] = vV.AsString()
}
b.labels = labels
}
ns := data.String("namespace")
b.namespace = ns
b.nameSuffix = data.String("secret_suffix")
if hasNumericSuffix(b.nameSuffix, "-") {
// If the last segment is a number, it's considered invalid.
// The backend automatically appends its own numeric suffix when chunking large state files into multiple secrets.
// Allowing a user-defined numeric suffix could cause conflicts with this mechanism.
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("secret_suffix must not end with '-<number>', got %q", b.nameSuffix),
)
}
b.config = cfg
return nil
}
func getInitialConfig(data backendbase.SDKLikeData) (*restclient.Config, error) {
var cfg *restclient.Config
var err error
inCluster := data.Bool("in_cluster_config")
if inCluster {
cfg, err = restclient.InClusterConfig()
if err != nil {
return nil, err
}View on GitHub (pinned to c9def3e214)
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.
Example fix
# before - suffix ends in a number, collides with chunk indexing
secret_suffix = "myapp-${var.env}-1"
# after - final segment is non-numeric
secret_suffix = "myapp-${var.env}-state" Defensive patterns
Strategy: validation
Validate before calling
// Validate secret_suffix shape before configuring the backend
func validSecretSuffix(s string) bool {
parts := strings.Split(s, "-")
if _, err := strconv.Atoi(parts[len(parts)-1]); err == nil {
return false // last segment is numeric -> rejected
}
return true
} Type guard
func isValidK8sSecretSuffix(s string) bool {
if s == "" { return false }
parts := strings.Split(s, "-")
if _, err := strconv.Atoi(parts[len(parts)-1]); err == nil {
return false
}
return true
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to configure: %s
- Failed to initialize kubernetes configuration: %s
- can't delete default state
- %v Additionally, unlocking the state in Kubernetes faile
- state is already unlocked
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/65af2a4e8068ccc9.
Report an issue: GitHub.