hashicorp/terraform · error
failed to parse lock_address URL
Error message
failed to parse lock_address URL: %s
What it means
url.Parse returned an error for the lock_address value (attribute or TF_HTTP_LOCK_ADDRESS). The string is malformed enough that Go's URL parser rejects it outright — control characters, raw spaces, invalid percent-encoding, or unbalanced IPv6 brackets. Unlike the address, lock_address is optional and only validated when non-null.
Solutions
- Percent-encode any spaces/special characters in the URL or remove them.
- Ensure lock_address is a single line with no embedded newlines/control characters.
- Validate with: printf '%s' "$TF_HTTP_LOCK_ADDRESS" | grep -P '[\x00-\x1f]' to detect control chars.
- Use an absolute http(s) URL identical in shape to the working 'address' value.
Example fix
// before lock_address = "https://state.example.com/lock default" // after lock_address = "https://state.example.com/lock%20default"
Defensive patterns
Strategy: validation
Validate before calling
# Pre-flight: validate lock_address parses and has no control chars
if [ -n "$TF_HTTP_LOCK_ADDRESS" ]; then
printf '%s' "$TF_HTTP_LOCK_ADDRESS" | grep -P '[\x00-\x1f]' && { echo 'control chars in lock_address'; exit 1; }
case "$TF_HTTP_LOCK_ADDRESS" in http://*|https://*) ;; *) echo 'lock_address missing http(s) scheme'; exit 1;; esac
fi Prevention
- Build lock_address from the same base URL as address to keep encoding consistent.
- Percent-encode any dynamic path segments.
- Run a pre-flight check for control characters whenever the value is templated.
When it happens
Trigger: lock_address contains raw spaces or control characters, an invalid '%' escape (e.g. '%zz'), unbalanced '[' for an IPv6 literal, or a stray newline inserted by a templating tool.
Common situations: lock_address built from a template that left an unencoded space; env var sourced from a secret store with a trailing newline; copy-paste across terminals introduced a carriage return.
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
- lock_address must be HTTP or HTTPS
- address must be HTTP or HTTPS
- failed to parse unlock_address URL
- Unexpected HTTP response code
- unlock_address must be HTTP or HTTPS
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/0ddf4ab365d24312.
Report an issue: GitHub.
Appendix: 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 d32a084675)