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

  1. Choose a secret_suffix whose last hyphen-separated segment is non-numeric (e.g. 'app-prod' instead of 'app-1').
  2. Move any numeric component earlier in the suffix so the final segment is textual.
  3. 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

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


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/65af2a4e8068ccc9. Report an issue: GitHub.