{"record":{"id":"e35821f17e0249af","repo":"hashicorp/terraform","slug":"http-remote-state-endpoint-requires-auth","errorCode":null,"errorMessage":"HTTP remote state endpoint requires auth","messagePattern":"HTTP remote state endpoint requires auth","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"internal/backend/remote-state/http/client.go","lineNumber":99,"sourceCode":"\tif c.LockURL == nil {\n\t\treturn \"\", nil\n\t}\n\tc.lockID = \"\"\n\n\tjsonLockInfo := info.Marshal()\n\tresp, err := c.httpRequest(c.LockMethod, c.LockURL, &jsonLockInfo, \"lock\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\n\tswitch resp.StatusCode {\n\tcase http.StatusOK:\n\t\tc.lockID = info.ID\n\t\tc.jsonLockInfo = jsonLockInfo\n\t\treturn info.ID, nil\n\tcase http.StatusUnauthorized:\n\t\treturn \"\", fmt.Errorf(\"HTTP remote state endpoint requires auth\")\n\tcase http.StatusForbidden:\n\t\treturn \"\", fmt.Errorf(\"HTTP remote state endpoint invalid auth\")\n\tcase http.StatusConflict, http.StatusLocked:\n\t\tdefer resp.Body.Close()\n\t\tbody, err := io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn \"\", &statemgr.LockError{\n\t\t\t\tErr: fmt.Errorf(\"HTTP remote state already locked, failed to read body\"),\n\t\t\t}\n\t\t}\n\t\texisting := statemgr.LockInfo{}\n\t\terr = json.Unmarshal(body, &existing)\n\t\tif err != nil {\n\t\t\treturn \"\", &statemgr.LockError{\n\t\t\t\tErr: fmt.Errorf(\"HTTP remote state already locked, failed to unmarshal body\"),\n\t\t\t}\n\t\t}\n\t\treturn \"\", &statemgr.LockError{","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/http/client.go#L81-L117","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nbackend \"http\" {\n  address = \"https://state.corp/state\"\n}\n// after\nbackend \"http\" {\n  address  = \"https://state.corp/state\"\n  username = var.state_user\n  password = var.state_pass\n}","handlingStrategy":"validation","validationCode":"func validateAuth(user, pass string) error {\n  if user == \"\" || pass == \"\" {\n    return fmt.Errorf(\"state server requires username/password\")\n  }\n  return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["auth","http","locking","http-backend","terraform"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}