hashicorp/terraform · error
failed to parse unlock_address URL: %s
Error message
failed to parse unlock_address URL: %s
What it means
Thrown by the HTTP backend's Configure step when url.Parse() rejects the value supplied via the unlock_address backend argument or the TF_HTTP_UNLOCK_ADDRESS env var. The '%s' carries the underlying net/url parse error, typically an unescaped control character, space, or malformed scheme delimiter. The unlock URL is only parsed when a value is provided (the attribute is optional), so this fires only on an explicitly configured unlock endpoint.
Source
Thrown at internal/backend/remote-state/http/backend.go:173
}
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 {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("failed to parse unlock_address URL: %s", err),
)
}
if unlockURL.Scheme != "http" && unlockURL.Scheme != "https" {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("unlock_address must be HTTP or HTTPS"),
)
}
}
unlockMethod := backendbase.GetAttrEnvDefaultFallback(
configVal, "unlock_method",
"TF_HTTP_UNLOCK_METHOD", cty.StringVal("UNLOCK"),
).AsString()
retryMax, err := backendbase.IntValue(
backendbase.GetAttrEnvDefaultFallback(
configVal, "retry_max",
"TF_HTTP_RETRY_MAX", cty.NumberIntVal(2),
),View on GitHub (pinned to c9def3e214)
Solutions
- Inspect the exact value in unlock_address (or TF_HTTP_UNLOCK_ADDRESS) and percent-encode any spaces or special characters.
- Ensure the value includes an explicit http:// or https:// scheme prefix.
- Validate the URL with `echo "$TF_HTTP_UNLOCK_ADDRESS" | xargs -n1 python3 -c 'import sys,urllib.parse;urllib.parse.urlparse(sys.argv[1])'` before running terraform.
- If the address is generated by a script, run it through url.PathEscape/url.QueryEscape for the path and query portions.
Example fix
// before
backend "http" {
unlock_address = "http://state.corp/unlock my workspace"
}
// after
backend "http" {
unlock_address = "http://state.corp/unlock%20my%20workspace"
} Defensive patterns
Strategy: validation
Validate before calling
// Validate unlock_address before terraform init
import (
"fmt"
"net/url"
)
func validateUnlockURL(raw string) error {
u, err := url.Parse(raw)
if err != nil { return fmt.Errorf("unlock_address unparseable: %w", err) }
if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("unlock_address scheme %q not allowed", u.Scheme)
}
return nil
} Prevention
- Percent-encode spaces and special chars in any URL set from templates or env vars.
- Always include an explicit http:// or https:// scheme.
- Lint backend config values in CI with a URL parser before terraform init.
When it happens
Trigger: Setting unlock_address to a string with unencoded spaces (e.g. "http://host/unlock my state"), missing the scheme ("//host/unlock"), a raw IPv6 address without brackets, or any value net/url.Parse cannot accept. Triggered during `terraform init` or any run that re-configures the backend.
Common situations: Operators paste a URL containing spaces or query parameters into the unlock_address field without percent-encoding; CI sets TF_HTTP_UNLOCK_ADDRESS from an unescaped template variable; a trailing slash or stray character copied from a wiki.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unlock_address must be HTTP or HTTPS
- invalid retry_max: %s
- invalid retry_wait_min: %s
- invalid retry_wait_max: %s
- client_certificate_pem is set but client_private_key_pem is
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/c8bf6189840c67bc.
Report an issue: GitHub.