hashicorp/terraform · warning

key can not start and end with '/'

Error message

key can not start and end with '/'

What it means

ValidateFunc for the cos backend's `key` attribute (cos/backend.go:148). Despite the message wording ('start and end'), the code rejects a key that starts OR ends with '/'. Such keys would be directory markers or root-relative and are invalid as the state object key.

Source

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

				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,
				Optional:    true,
				Description: "Whether to enable server side encryption of the state file",
				Default:     true,
			},
			"acl": {
				Type:        schema.TypeString,
				Optional:    true,
				Description: "Object ACL to be applied to the state file",
				Default:     "private",
				ValidateFunc: func(v interface{}, s string) ([]string, []error) {
					value := v.(string)
					if value != "private" && value != "public-read" {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Ensure key has neither a leading nor trailing slash, e.g. key = "terraform.tfstate".
  2. Use the default key (terraform.tfstate) when in doubt.
  3. Put directory structure in prefix, not in key.

Example fix

// before
terraform {
  backend "cos" {
    key = "/terraform.tfstate"
  }
}
// after
terraform {
  backend "cos" {
    key = "terraform.tfstate"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

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

Prevention

When it happens

Trigger: Setting key = "/terraform.tfstate" or key = "env/" in the backend block; the ValidateFunc errors on HasPrefix("/") or HasSuffix("/").

Common situations: Pasting a leading slash from a URL; a trailing-slash typo; confusing the key with the prefix.

Related errors


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