The "read-only file system" error occurs when Terraform cannot write to directories needed for state files, plugins, or temporary operations. This typically happens in containerized or restricted environments. Fix by ensuring writable directories are available and properly mounted.
The "read-only file system" error indicates that Terraform is attempting to write to a directory or file on a filesystem that has been mounted or configured as read-only. Terraform needs write access to several locations: 1. The working directory (for .terraform/ plugins and lock files) 2. The state file directory (for terraform.tfstate and backups) 3. Temporary directories (for provider caching and operations) When any of these locations are read-only, Terraform operations fail at the point where a write is attempted.
Check if the filesystem is mounted as read-only:
# Check mount status
mount | grep " / "
# Look for "ro" flag - if you see it, filesystem is read-only
# Try to touch a test file in working directory
touch test-file.txt
rm test-file.txtIf you see "(ro)" in the mount output, the filesystem is read-only.
A full disk can cause the kernel to remount as read-only:
# Check available space
df -h
# Look for 100% usage - this is critical
df -i # Check inode usage too
# Clean up if needed
rm -rf /path/to/large/filesFree up disk space and the filesystem may remount automatically as writable.
Ensure you have write permissions:
# Check current directory permissions
ls -ld .
# Check if you can write (should complete without error)
touch .test-write && rm .test-write
# If permission denied, check user/group
id
groups
# Fix permissions if needed
chmod u+w .The working directory must be writable by the user running Terraform.
Ensure the working directory is on a writable volume:
# Run with writable volume
docker run -v /path/to/writable:/work \
-w /work \
hashicorp/terraform:latest init
# Or in docker-compose.yml
services:
terraform:
image: hashicorp/terraform:latest
volumes:
- ./terraform:/work
- terraform-cache:/root/.terraform.d
working_dir: /work
volumes:
terraform-cache:Avoid mounting directories as read-only (no :ro flag).
If the default location is read-only, redirect to a writable location:
# Set to writable directory
export TF_DATA_DIR=/tmp/.terraform
# Or in environment during apply
TF_DATA_DIR=/writable/path terraform init
TF_DATA_DIR=/writable/path terraform applyThis moves plugin cache and working files to a writable location.
If the filesystem was remounted read-only due to errors:
# Check current mounts
mount | grep " / "
# Remount as writable (requires sudo)
sudo mount -o remount,rw /
# Or for specific partition
sudo mount -o remount,rw /varThis is a temporary fix. Investigate why it was marked read-only (disk errors, full disk, etc.).
Store state remotely instead of locally:
# terraform.tf
terraform {
cloud {
organization = "my-org"
workspaces {
name = "my-workspace"
}
}
}
# Or with S3
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
}
}Remote backends bypass local filesystem write requirements for state.
In Kubernetes or Fargate environments, ensure persistent volumes are mounted at the working directory. The /tmp directory is commonly used for plugin caching - verify it's writable or set TF_PLUGIN_CACHE_DIR to an alternative. Some container security profiles (AppArmor, SELinux) can prevent writes - check logs with dmesg or journalctl for denials. In CI/CD systems like GitHub Actions or GitLab CI, the runner's filesystem is usually writable by default, but custom runners may have restrictions. For immutable infrastructure patterns, consider Terraform Cloud for state management and run operations to eliminate local filesystem requirements entirely.
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