hashicorp/terraform · error
failed to parse address URL
Error message
failed to parse address URL: %s
What it means
Thrown by the HTTP backend when url.Parse(address) returns an error. The address string was non-empty but malformed enough that Go's net/url rejects it (e.g., control characters, missing scheme with invalid characters, or an unparseable URL).
Solutions
- Inspect the address for stray whitespace, newlines, or control characters and remove them.
- Ensure the address includes a scheme (http:// or https://).
- Print the resolved address before terraform runs to catch interpolation bugs.
- Use trimprefix/trimsuffix/trimspace on the variable producing the URL.
Example fix
// before
address = " ${var.state_url}" # leading space
// after
address = trimspace(var.state_url) Defensive patterns
Strategy: validation
Validate before calling
address := strings.TrimSpace(rawAddress)
if address == "" {
return fmt.Errorf("address is empty")
}
u, err := url.Parse(address)
if err != nil {
return fmt.Errorf("address is not a valid URL: %w", err)
}
if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("address must use http or https")
} Type guard
func isValidHTTPURL(s string) bool {
u, err := url.Parse(strings.TrimSpace(s))
return err == nil && (u.Scheme == "http" || u.Scheme == "https")
} Prevention
- Trim whitespace from URL-producing variables.
- Always include the scheme in the address.
- Add a CI lint that url.Parses the address and asserts http/https scheme.
When it happens
Trigger: url.Parse(address) returns a non-nil error — typically a stray space or control character in the URL, a missing scheme combined with other invalid syntax, or a value that is not a URL at all.
Common situations: Variable interpolation leaves a leading space; address was built by string concatenation that introduced a newline; user pasted a path without scheme; trailing slash issues are not this error (those parse fine).
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
- address argument is required
- argument is required
- attribute is required
- auth must be one of ' ' or ' ' or ' ' or ' ' or ' ' or
- building Storage Accounts client: %+v
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/578d0498e6a728a5.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/http/backend.go:133
backendbase.Base
client *httpClient
}
func (b *Backend) Configure(configVal cty.Value) tfdiags.Diagnostics {
address := backendbase.GetAttrEnvDefaultFallback(
configVal, "address",
"TF_HTTP_ADDRESS", cty.StringVal(""),
).AsString()
if address == "" {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("address argument is required"),
)
}
updateURL, err := url.Parse(address)
if err != nil {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("failed to parse address URL: %s", err),
)
}
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 {View on GitHub (pinned to d32a084675)