{"record":{"id":"3819763c7e06247d","repo":"hashicorp/terraform","slug":"lock-address-must-be-http-or-https","errorCode":null,"errorMessage":"lock_address must be HTTP or HTTPS","messagePattern":"lock_address must be HTTP or HTTPS","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/http/backend.go","lineNumber":158,"sourceCode":"\t}\n\n\tupdateMethod := backendbase.GetAttrEnvDefaultFallback(\n\t\tconfigVal, \"update_method\",\n\t\t\"TF_HTTP_UPDATE_METHOD\", cty.StringVal(\"POST\"),\n\t).AsString()\n\n\tvar lockURL *url.URL\n\tif v := backendbase.GetAttrEnvDefault(configVal, \"lock_address\", \"TF_HTTP_LOCK_ADDRESS\"); !v.IsNull() {\n\t\tvar err error\n\t\tlockURL, err = url.Parse(v.AsString())\n\t\tif err != nil {\n\t\t\treturn backendbase.ErrorAsDiagnostics(\n\t\t\t\tfmt.Errorf(\"failed to parse lock_address URL: %s\", err),\n\t\t\t)\n\t\t}\n\t\tif lockURL.Scheme != \"http\" && lockURL.Scheme != \"https\" {\n\t\t\treturn backendbase.ErrorAsDiagnostics(\n\t\t\t\tfmt.Errorf(\"lock_address must be HTTP or HTTPS\"),\n\t\t\t)\n\t\t}\n\t}\n\tlockMethod := backendbase.GetAttrEnvDefaultFallback(\n\t\tconfigVal, \"lock_method\",\n\t\t\"TF_HTTP_LOCK_METHOD\", cty.StringVal(\"LOCK\"),\n\t).AsString()\n\n\tvar unlockURL *url.URL\n\tif v := backendbase.GetAttrEnvDefault(configVal, \"unlock_address\", \"TF_HTTP_UNLOCK_ADDRESS\"); !v.IsNull() {\n\t\tvar err error\n\t\tunlockURL, err = url.Parse(v.AsString())\n\t\tif err != nil {\n\t\t\treturn backendbase.ErrorAsDiagnostics(\n\t\t\t\tfmt.Errorf(\"failed to parse unlock_address URL: %s\", err),\n\t\t\t)\n\t\t}\n\t\tif unlockURL.Scheme != \"http\" && unlockURL.Scheme != \"https\" {","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/http/backend.go#L140-L176","documentation":"lock_address parsed successfully but its scheme is neither 'http' nor 'https'. The backend applies the same scheme restriction to lock_address as it does to address, so an ftp/file/s3 scheme (or a URL that url.Parse accepts but with an unexpected scheme) is rejected.","triggerScenarios":"lock_address set with a non-HTTP scheme such as 'ftp://', 'file://', or a relative URL whose parsed scheme is empty yet bypassed the parse check (rare); most often a wrong-scheme copy-paste.","commonSituations":"lock_address copied from a different backend's URI; lock_address templated from a variable that accidentally prepended a non-http scheme.","solutions":["Set lock_address to an http:// or https:// URL.","Mirror the scheme of the main 'address' — typically 'https://.../lock' alongside 'https://...'.","Remove lock_address entirely if you do not need HTTP-level locking (the backend then runs lockless)."],"exampleFix":"// before\nlock_address = \"ftp://state.example.com/lock\"\n// after\nlock_address = \"https://state.example.com/lock\"","handlingStrategy":"validation","validationCode":"# Pre-flight: assert lock_address scheme\nif [ -n \"$TF_HTTP_LOCK_ADDRESS\" ]; then\n  case \"$TF_HTTP_LOCK_ADDRESS\" in\n    http://*|https://*) echo ok ;;\n    *) echo \"ERROR: lock_address must be http(s): $TF_HTTP_LOCK_ADDRESS\"; exit 1 ;;\n  esac\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep lock_address scheme identical to address (both https in production).","Omit lock_address entirely if you do not need HTTP-level locking."],"tags":["config","url-validation","http-backend","scheme","lock"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}