hashicorp/terraform · error

failed to parse lock_address URL: %s

Error message

failed to parse lock_address URL: %s

What it means

When lock_address is provided (config or TF_HTTP_LOCK_ADDRESS), Configure() parses it with url.Parse. A malformed lock URL (control chars, bad escapes) yields this error mirroring the address check. If lock_address is unset, parsing is skipped and no error fires.

Source

Thrown at internal/backend/remote-state/http/backend.go:153

	}
	if updateURL.Scheme != "http" && updateURL.Scheme != "https" {
		return backendbase.ErrorAsDiagnostics(
			fmt.Errorf("address must be HTTP or HTTPS"),
		)
	}

	updateMethod := backendbase.GetAttrEnvDefaultFallback(
		configVal, "update_method",
		"TF_HTTP_UPDATE_METHOD", cty.StringVal("POST"),
	).AsString()

	var lockURL *url.URL
	if v := backendbase.GetAttrEnvDefault(configVal, "lock_address", "TF_HTTP_LOCK_ADDRESS"); !v.IsNull() {
		var err error
		lockURL, err = url.Parse(v.AsString())
		if err != nil {
			return backendbase.ErrorAsDiagnostics(
				fmt.Errorf("failed to parse lock_address URL: %s", err),
			)
		}
		if lockURL.Scheme != "http" && lockURL.Scheme != "https" {
			return backendbase.ErrorAsDiagnostics(
				fmt.Errorf("lock_address must be HTTP or HTTPS"),
			)
		}
	}
	lockMethod := backendbase.GetAttrEnvDefaultFallback(
		configVal, "lock_method",
		"TF_HTTP_LOCK_METHOD", cty.StringVal("LOCK"),
	).AsString()

	var unlockURL *url.URL
	if v := backendbase.GetAttrEnvDefault(configVal, "unlock_address", "TF_HTTP_UNLOCK_ADDRESS"); !v.IsNull() {
		var err error
		unlockURL, err = url.Parse(v.AsString())
		if err != nil {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Make lock_address a valid URL (URL-encode any special components).
  2. Ensure the scheme + host + path match the address style.
  3. If you don't need a separate lock endpoint, unset lock_address (the backend supports lockless operation).

Example fix

// before
lock_address = "https://state.example.com/lock/my team"

// after
lock_address = "https://state.example.com/lock/my%20team"
Defensive patterns

Strategy: validation

Validate before calling

if lockAddr != "" {
    if _, err := url.Parse(lockAddr); err != nil {
        log.Fatalf("lock_address is not a valid URL: %v", err)
    }
}

Type guard

func isValidLockURL(s string) bool {
    if s == "" { return true }
    _, err := url.Parse(s)
    return err == nil
}

Prevention

When it happens

Trigger: Setting lock_address to a string with invalid URL syntax (unencoded spaces, control characters, stray backslashes) in 'terraform init'.

Common situations: lock_address built by concatenation producing malformed escapes; copy-paste with spaces; mismatch where address is clean but lock_address has a typo.

Understand the failure class

Related errors


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