hashicorp/terraform · warning

prefix must not start with '/' or './'

Error message

prefix must not start with '/' or './'

What it means

ValidateFunc for the cos backend's `prefix` attribute (cos/backend.go:136). Object-key prefixes in COS must be relative; a leading '/' or './' would produce malformed keys, so configuration validation rejects it before the backend is configured.

Source

Thrown at internal/backend/remote-state/cos/backend.go:136

				Type:        schema.TypeString,
				Optional:    true,
				Description: "The custom endpoint for the COS API, e.g. http://cos-internal.{Region}.tencentcos.cn. Both HTTP and HTTPS are accepted.",
				DefaultFunc: schema.EnvDefaultFunc(PROVIDER_ENDPOINT, nil),
			},
			"domain": {
				Type:        schema.TypeString,
				Optional:    true,
				DefaultFunc: schema.EnvDefaultFunc(PROVIDER_DOMAIN, nil),
				Description: "The root domain of the API request. Default is tencentcloudapi.com.",
			},
			"prefix": {
				Type:        schema.TypeString,
				Optional:    true,
				Description: "The directory for saving the state file in bucket",
				ValidateFunc: func(v interface{}, s string) ([]string, []error) {
					prefix := v.(string)
					if strings.HasPrefix(prefix, "/") || strings.HasPrefix(prefix, "./") {
						return nil, []error{fmt.Errorf("prefix must not start with '/' or './'")}
					}
					return nil, nil
				},
			},
			"key": {
				Type:        schema.TypeString,
				Optional:    true,
				Description: "The path for saving the state file in bucket",
				Default:     "terraform.tfstate",
				ValidateFunc: func(v interface{}, s string) ([]string, []error) {
					if strings.HasPrefix(v.(string), "/") || strings.HasSuffix(v.(string), "/") {
						return nil, []error{fmt.Errorf("key can not start and end with '/'")}
					}
					return nil, nil
				},
			},
			"encrypt": {
				Type:        schema.TypeBool,

View on GitHub (pinned to c9def3e214)

Solutions

  1. Remove any leading '/' or './' from prefix, e.g. prefix = "env/state".
  2. Treat prefix as a relative object key prefix, not a filesystem path.
  3. Leave prefix unset if you want state at the bucket root.

Example fix

// before
terraform {
  backend "cos" {
    prefix = "/terraform/prod"
  }
}
// after
terraform {
  backend "cos" {
    prefix = "terraform/prod"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the cos prefix before passing it to the backend
func validPrefix(p string) error {
    if strings.HasPrefix(p, "/") || strings.HasPrefix(p, "./") {
        return fmt.Errorf("prefix must not start with '/' or './'")
    }
    return nil
}

Prevention

When it happens

Trigger: Setting prefix = "/env/state" or prefix = "./env/state" in the backend block triggers the ValidateFunc which checks HasPrefix("/") or HasPrefix("./").

Common situations: Copying a local filesystem path that begins with '/' into the prefix; assuming prefix behaves like an absolute path; migrating from an S3 backend with a leading slash.

Related errors


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