hashicorp/terraform · error

key can not start and end with '/'

Error message

key can not start and end with '/'

What it means

Schema-level ValidateFunc for the COS backend 'key' attribute (the object filename). Leading or trailing slashes would create an empty path segment or a directory-like key, so they are rejected at terraform init time.

Solutions

  1. Use a bare filename or a slash-separated path with no leading or trailing slash, e.g. 'terraform.tfstate' or 'prod/terraform.tfstate'.
  2. Re-run terraform init.

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 backend key before terraform init.
func validateCOSKey(key string) error {
    if strings.HasPrefix(key, "/") || strings.HasSuffix(key, "/") {
        return fmt.Errorf("key can not start and end with '/'")
    }
    return nil
}

Prevention

When it happens

Trigger: terraform init with a `key` value starting with '/' or ending with '/'.

Common situations: User sets key = '/terraform.tfstate' by analogy with S3; sets key = 'envs/' intending a folder; copies a full path with slashes at both ends.

Related errors


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

Appendix: 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 d32a084675)