hashicorp/terraform · error
HTTP remote state endpoint invalid auth
Error message
HTTP remote state endpoint invalid auth
What it means
During Lock(), the server returned 403 Forbidden: credentials were accepted but are not permitted to lock this state. Distinct from 401 (error 250) which is missing/unrecognized credentials.
Source
Thrown at internal/backend/remote-state/http/client.go:101
}
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{
Info: &existing,
Err: fmt.Errorf("HTTP remote state already locked: ID=%s", existing.ID),View on GitHub (pinned to c9def3e214)
Solutions
- Grant the configured principal permission to lock (and unlock) the state path on the server.
- Verify with `curl -u user:pass -X LOCK <lock_address>` returns 200, not 403.
- Switch to a credential that has the required lock/unlock ACLs.
Example fix
// before: token scoped read-only
// after: grant lock+unlock on the state path
// policy on server (example):
// path "state/*" { capabilities = ["create","read","update","delete","lock","unlock"] } Defensive patterns
Strategy: validation
Validate before calling
// Verify lock permission against the real endpoint before terraform apply
func canLock(lockURL, user, pass string) error {
req, _ := http.NewRequest("LOCK", lockURL, nil)
req.SetBasicAuth(user, pass)
resp, err := http.DefaultClient.Do(req)
if err != nil { return err }
defer resp.Body.Close()
if resp.StatusCode == http.StatusForbidden {
return fmt.Errorf("principal lacks lock permission")
}
return nil
} Prevention
- Grant the principal explicit lock+unlock ACLs on the state path.
- Pre-flight the lock endpoint with curl in CI.
- Use dedicated state-management credentials, not deploy-only tokens.
When it happens
Trigger: Valid user lacking the lock ACL on the workspace; correct token scoped read-only; path-level policy denying the LOCK method on the state endpoint. Fires at lock acquisition time during apply/plan/destroy.
Common situations: Service account rotated to lower privileges; new workspace with default restrictive policy; token environment variable pointing at a CI deploy token instead of a state-management token.
Related errors
- HTTP remote state endpoint requires auth
- HTTP remote state already locked, failed to read body
- HTTP remote state already locked, failed to unmarshal body
- HTTP remote state already locked: ID=%s
- Unexpected HTTP response code %d
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/135f9f6485a2d9bf.
Report an issue: GitHub.