opentofu/opentofu · error
failed to parse address URL: %w
Error message
failed to parse address URL: %w
What it means
During configure(), the 'address' attribute is parsed with url.Parse and any error is wrapped as 'failed to parse address URL'. url.Parse rarely fails, but it does for structurally malformed URLs such as an unclosed IPv6 bracket or embedded control characters, so this fires before the http/https scheme check.
Source
Thrown at internal/backend/remote-state/http/backend.go:215
if clientCertificatePem != "" && clientPrivateKeyPem != "" {
// attach a client certificate to the TLS handshake (aka mTLS)
certificate, err := tls.X509KeyPair([]byte(clientCertificatePem), []byte(clientPrivateKeyPem))
if err != nil {
return fmt.Errorf("cannot load client certificate: %w", err)
}
tlsConfig.Certificates = []tls.Certificate{certificate}
}
return nil
}
func (b *Backend) configure(ctx context.Context) error {
data := schema.FromContextBackendConfig(ctx)
address := data.Get("address").(string)
updateURL, err := url.Parse(address)
if err != nil {
return fmt.Errorf("failed to parse address URL: %w", err)
}
if updateURL.Scheme != "http" && updateURL.Scheme != "https" {
return fmt.Errorf("address must be HTTP or HTTPS")
}
updateMethod := data.Get("update_method").(string)
var lockURL *url.URL
if v, ok := data.GetOk("lock_address"); ok && v.(string) != "" {
var err error
lockURL, err = url.Parse(v.(string))
if err != nil {
return fmt.Errorf("failed to parse lockAddress URL: %w", err)
}
if lockURL.Scheme != "http" && lockURL.Scheme != "https" {
return fmt.Errorf("lockAddress must be HTTP or HTTPS")
}
}View on GitHub (pinned to 3561785c48)
Solutions
- Print the fully rendered address and test it with curl to confirm it parses
- Fix the malformed component (close brackets, remove spaces, control characters, newlines)
- Set the complete URL as a single literal in the backend block instead of concatenating variables
Example fix
# before address = "https://[::1" # after address = "https://[::1]/state"
Defensive patterns
Strategy: validation
Validate before calling
// Validate the rendered address before tofu init
u, err := url.Parse(rawAddress)
if err != nil {
log.Fatalf("address does not parse: %v", err)
} Prevention
- Render the final address in CI logs and curl it before init
- Trim whitespace and newlines from variables that feed the address
- Prefer one full literal URL over concatenating parts
When it happens
Trigger: address = "https://[::1" (missing ']'), an address containing a control character or newline (often from a templated variable), or garbage produced by concatenating empty config pieces.
Common situations: Assembling the URL from multiple -backend-config flags or CI variables where one piece is empty or mangled; IPv6 literals typed by hand; secrets managers or env files returning values with trailing newlines.
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
- failed to parse lockAddress URL: %w
- failed to parse unlockAddress URL: %w
- %s "%s" name must not be empty and only contain A-Za-z0-9-_
- client_certificate_pem is set but client_private_key_pem is
- client_private_key_pem is set but client_certificate_pem is
AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15).
Data as JSON: /api/errors/e7affb113dc21c77.
Report an issue: GitHub.