hashicorp/terraform · error
HTTP remote state endpoint requires auth
Error message
HTTP remote state endpoint requires auth
What it means
During Lock(), the state server returned 401 Unauthorized. The backend sent a request to lock_address with the configured LockMethod (default LOCK) and either no credentials or credentials the server rejected. Distinct from 403 (error 251) which means credentials were accepted but lacked permission.
Source
Thrown at internal/backend/remote-state/http/client.go:99
if c.LockURL == nil {
return "", nil
}
c.lockID = ""
jsonLockInfo := info.Marshal()
resp, err := c.httpRequest(c.LockMethod, c.LockURL, &jsonLockInfo, "lock")
if err != nil {
return "", err
}
defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK:
c.lockID = info.ID
c.jsonLockInfo = jsonLockInfo
return info.ID, nil
case http.StatusUnauthorized:
return "", fmt.Errorf("HTTP remote state endpoint requires auth")
case http.StatusForbidden:
return "", fmt.Errorf("HTTP remote state endpoint invalid auth")
case http.StatusConflict, http.StatusLocked:
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", &statemgr.LockError{
Err: fmt.Errorf("HTTP remote state already locked, failed to read body"),
}
}
existing := statemgr.LockInfo{}
err = json.Unmarshal(body, &existing)
if err != nil {
return "", &statemgr.LockError{
Err: fmt.Errorf("HTTP remote state already locked, failed to unmarshal body"),
}
}
return "", &statemgr.LockError{View on GitHub (pinned to c9def3e214)
Solutions
- Set username and password (or TF_HTTP_USERNAME/TF_HTTP_PASSWORD) to valid credentials for the state server.
- Confirm the credentials work with `curl -u "$TF_HTTP_USERNAME:$TF_HTTP_PASSWORD" -X LOCK <lock_address>`.
- If the server uses tokens instead of basic auth, ensure an auth proxy translates them or pick a backend that supports the server's scheme.
Example fix
// before
backend "http" {
address = "https://state.corp/state"
}
// after
backend "http" {
address = "https://state.corp/state"
username = var.state_user
password = var.state_pass
} Defensive patterns
Strategy: validation
Validate before calling
func validateAuth(user, pass string) error {
if user == "" || pass == "" {
return fmt.Errorf("state server requires username/password")
}
return nil
} Prevention
- Always set username/password (or TF_HTTP_* env) when the state server requires auth.
- Verify creds with curl -u before terraform runs.
- Store creds in the secret manager, not the repo.
When it happens
Trigger: username/password not set while the server requires basic auth; credentials wrong; TF_HTTP_USERNAME/TF_HTTP_PASSWORD unset in CI. Fires during `terraform apply` when the backend attempts to acquire the state lock.
Common situations: Switched state server to one requiring auth but did not update backend credentials; rotated password not propagated to CI secrets; basic-auth header stripped by a proxy.
Related errors
- HTTP remote state endpoint invalid auth
- HTTP remote state already locked, failed to read body
- HTTP remote state already locked, failed to unmarshal body
- Unexpected HTTP response code %d
- Failed to make %s HTTP request: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/e35821f17e0249af.
Report an issue: GitHub.