The prompt blinked on the screen, but the file was gone. Your bucket was safe, but you hadn’t even run a delete. The culprit lurked in the terminal, not in your AWS S3 configuration. A Linux terminal bug had just clashed with your read-only IAM role, and the cost was time, trust, and a broken workflow.
When using AWS S3 read-only roles, the expectation is clear: no writes, no deletes, only reads. This works perfectly in the AWS API, AWS CLI, and SDKs. But the terminal introduces a hidden risk. Certain commands—especially those that pipe or paginate output—can trigger unintended calls that appear like writes. The result is errors that mislead you into thinking the permissions are wrong, when the issue is in the local terminal environment.
This bug happens most often when listing large S3 buckets with tools that cache or format output. Utilities like less, combined with AWS CLI output streaming, can cause the terminal to send signals that confuse the permission model. The AWS CLI reports an "AccessDenied" on what looks like a harmless read. Engineers who are unaware waste hours debugging IAM policies that are already correct.
Reproducing the problem is simple but dangerous in production. Using a read-only IAM role, run an S3 list command piped into a pager. Depending on your Linux distribution, your terminal's default pager can emit write-like signals during session management. These are rejected by AWS but still crash your job. On some systems, the issue is tied to terminal control sequences and file descriptor handling in shell utilities that were never designed with cloud object stores in mind.