The "Upload failed for" error occurs when Terraform cannot upload modules to a registry or files to remote resources. This typically results from authentication issues, permission problems, or malformed module files.
This error appears when Terraform attempts to upload a module version to the Terraform Cloud/Enterprise private module registry or when the file provisioner tries to copy files to a remote resource. The error message indicates the upload operation failed, but the specific cause varies depending on context. In module registry uploads, it usually means the module has invalid files (like broken symlinks) or authentication credentials are invalid. In file provisioning, it typically indicates permission issues on the target system or network connectivity problems.
Ensure you have valid API credentials for your Terraform Cloud or Enterprise instance. Run:
terraform loginThis will prompt you to paste an API token. Alternatively, set the environment variable:
export TF_TOKEN_app_terraform_io="your-api-token-here"For private registries, ensure your ~/.terraform.d/credentials.tfrc.json is properly configured:
{
"credentials": {
"app.terraform.io": {
"token": "your-api-token"
}
}
}Verify the credentials file has restrictive permissions:
chmod 600 ~/.terraform.d/credentials.tfrc.jsonIf uploading a module to the private registry, inspect the module directory for invalid files, particularly symlinks. List all files:
ls -la module-directory/Look for symlinks and verify they're valid:
find module-directory -type l -exec ls -l {} \;Remove or fix any broken symlinks:
find module-directory -type l ! -exec test -L {} \; -printIf a symlink is broken, either remove it or replace it with the actual file content. The module registry does not support symlinks pointing outside the module.
For file provisioner errors, ensure the target user has write permissions to the destination directory:
# Connect to the remote resource and check permissions
ssh user@host "ls -ld /destination/path"If permissions are insufficient, adjust them or upload to a user-writable directory first, then move files:
provisioner "remote-exec" {
inline = [
"mkdir -p /destination",
"chmod 755 /destination"
]
}
provisioner "file" {
source = "local/path"
destination = "/tmp/upload"
}
provisioner "remote-exec" {
inline = [
"mv /tmp/upload /destination/path"
]
}Verify connectivity from your Terraform client to the target endpoint:
# For Terraform Cloud/Enterprise
curl -I https://app.terraform.io/api/registry/v1/modules
# For remote hosts (SSH)
ssh -v user@host "echo ok"If the connection fails, check your firewall rules and VPN connection. For WinRM (Windows):
Test-WSMan -ComputerName hostnameIncrease the client timeout if the registry is slow to respond:
export TF_REGISTRY_CLIENT_TIMEOUT=10If the module upload is stuck in an invalid state ('reg_ingressing' status), delete it via the Terraform Cloud API and retry:
# Delete the module version (replace with your values)
curl -X DELETE \
-H "Authorization: Bearer $TF_TOKEN_app_terraform_io" \
https://app.terraform.io/api/registry/v1/modules/namespace/name/provider/versions/1.0.0Then push the module again:
terraform login
cd path/to/module
terraform initIf uploads are timing out, increase the timeout in your Terraform configuration:
provisioner "file" {
source = "local/file"
destination = "/remote/path"
connection {
type = "ssh"
user = "ec2-user"
private_key = file("~/.ssh/id_rsa")
host = self.public_ip
timeout = "5m"
}
}For large files or many files, consider uploading a compressed archive instead and extracting on the remote end.
For rootless Docker installations or other containerized Terraform environments, ensure the container has proper network access to the registry endpoint. When using Terraform Cloud with VCS integration, uploads are handled automatically; verify your VCS webhook is configured correctly. For file provisioner uploads using WinRM to Windows instances, enable verbose logging with 'TF_LOG=DEBUG' to diagnose upstream winrmcp library issues. If using self-hosted Terraform Enterprise with S3 or blob storage backends, verify the storage bucket permissions match your instance's execution role.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: Error creating GKE Cluster: BadRequest
BadRequest error creating GKE cluster in Terraform
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform