hashicorp/terraform · error
lock_address must be HTTP or HTTPS
Error message
lock_address must be HTTP or HTTPS
What it means
After parsing lock_address, Configure() enforces scheme http or https, identical to the address-scheme check. A non-HTTP(S) scheme or empty scheme (URL without protocol prefix) is rejected because the lock call must be an HTTP request.
Source
Thrown at internal/backend/remote-state/http/backend.go:158
}
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 {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("failed to parse unlock_address URL: %s", err),
)
}
if unlockURL.Scheme != "http" && unlockURL.Scheme != "https" {View on GitHub (pinned to c9def3e214)
Solutions
- Prefix lock_address with 'https://' (or 'http://' for local dev).
- Remove lock_address entirely if your state API has no separate lock endpoint.
- Confirm scheme matches address; the HTTP backend does not inherit it automatically.
Example fix
// before lock_address = "state.example.com/lock" // no scheme // after lock_address = "https://state.example.com/lock"
Defensive patterns
Strategy: validation
Validate before calling
if lockAddr != "" {
u, err := url.Parse(lockAddr)
if err != nil { log.Fatal(err) }
if u.Scheme != "http" && u.Scheme != "https" {
log.Fatalf("lock_address scheme must be http or https, got %q", u.Scheme)
}
} Type guard
func isHTTPScheme(s string) bool {
u, err := url.Parse(s)
return err == nil && (u.Scheme == "http" || u.Scheme == "https")
} Prevention
- Always prefix lock_address with https://.
- Keep scheme consistent with address.
- Omit lock_address entirely when not using a separate lock endpoint.
When it happens
Trigger: lock_address set to a value without an http(s):// scheme, or to ftp/file/etc. Triggered during 'terraform init' when lock_address is set.
Common situations: User set lock_address without a scheme assuming the backend would reuse address's scheme; copy-paste dropped the prefix; non-HTTP scheme by mistake.
Related errors
- address must be HTTP or HTTPS
- failed to parse lock_address URL: %s
- address argument is required
- failed to parse address URL: %s
- consul lock was lost
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/3819763c7e06247d.
Report an issue: GitHub.