K8s Troubleshooting - "Err:30"
Error
map[DriverName:filesystem Enclosed:map[Err:30 Op:mkdir Path:/var/lib/registry/docker/registry/v2/repositories/<project>/<repository>]]
This error commonly surfaces in Harbor registry pods running on Kubernetes.
Root Cause
Err:30 is the Linux kernel error code -EROFS — Error: Read-Only File System. The pod is attempting a write operation (mkdir) on a path that is backed by a read-only volume mount.
This typically happens when:
- A
PersistentVolumeis mounted withaccessModes: ReadOnlyManyinstead ofReadWriteOnceorReadWriteMany - The underlying storage (NFS, Ceph, etc.) remounted as read-only due to an I/O error or quota breach
- A node-level disk issue caused the filesystem to flip to read-only mode as a self-protection measure
- A misconfigured
volumeMountin the pod spec hasreadOnly: true
Diagnosis
Step 1 — Find the registry pod:
POD=$(kubectl get pods -n <HARBOR_NAMESPACE> \
-l goharbor.io/operator-controller=registry \
-o name --kubeconfig=/path/to/kubeconfig)
echo $POD
Step 2 — Check the mount flags:
kubectl --kubeconfig=/path/to/kubeconfig \
-n <HARBOR_NAMESPACE> exec $POD -- mount | grep /var/lib/registry
Look for ro in the mount options. A healthy mount will show rw:
/dev/sdb on /var/lib/registry type ext4 (rw,relatime) ✅ healthy
/dev/sdb on /var/lib/registry type ext4 (ro,relatime) ❌ read-only
Step 3 — Check PVC access mode:
kubectl get pvc -n <HARBOR_NAMESPACE> --kubeconfig=/path/to/kubeconfig
Verify ACCESS MODES is RWO or RWX, not ROX.
Step 4 — Check node-level disk health:
# SSH into the node hosting the pod
dmesg | grep -i "read-only\|remount\|I/O error" | tail -20
journalctl -k | grep -i "ext4\|xfs\|ceph" | tail -20
Resolution
| Cause | Fix |
|---|---|
PVC mounted ReadOnly |
Update the PVC/PV to ReadWriteOnce and re-attach |
| Disk I/O error → auto-remount | Investigate disk health (smartctl, fsck), then remount rw |
Pod-level readOnly: true in volumeMount |
Remove readOnly: true from the container spec |
Quota exceeded → forced ro |
Free space or increase quota, then remount |
Quick fix — delete and recreate the pod (forces re-attachment of the volume):
kubectl delete $POD -n <HARBOR_NAMESPACE> --kubeconfig=/path/to/kubeconfig
The new pod will re-mount the PV. If the volume re-attaches as rw, the issue was transient. If it attaches as ro again, the root cause is in the storage layer and requires deeper investigation.
Prevention
- Set resource quotas and storage limits to avoid disk exhaustion
- Enable storage monitoring alerts (e.g.,
kubelet_volume_stats_available_bytesin Prometheus) - Use
ReadWriteOncefor stateful single-replica workloads; avoidReadOnlyManyfor writable paths