[BUG] .claudeignore does not prevent Claude from reading ignored files
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The .claudeignore file is documented as a way to exclude files from Claude's context. However, Claude would appear to still be able to explicitly read files listed in .claudeignore (possibly using a read tool?), effectively bypassing the ignore rules.
What Should Happen?
Claude appears to read ignored files even if those files are listed in .claudeignore.
This makes the feature unreliable for excluding certain files.
Impact:
Users relying on .claudeignore to protect files have no real guarantee that those files are excluded from context.
This behavior has been observed both when using Claude from the terminal and via the VS Code extension.
Error Messages/Logs
Steps to Reproduce
- Add examplefile.json to .claudeignore 2. Ask Claude to show one of files listed in claudeignore 3. Claude reads and displays the content of file
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.79
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
VS Code integrated terminal
Additional Information
This issue was observed while using Claude through the monthly subscription, not the Anthropic API. Specifically, it occurs when using Claude from the terminal and the VS Code extension.
The .claudeignore file was placed in the root of the project and was recognized by Claude.
19 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
This is really annoying. Also it is not clear when claude code will ask for read permission and when it is just reading files out of the blue.
Can you link me the official documentation?
came here to report the same.
@matt-savvy if you ask claude (on web) example "how do i restrict claude code from reading .env", it would reply with
In Claude Code, add a .claudeignore file in your project root. Claude Code respects this file and will not read, reference, or suggest changes to anything listed in it — same concept as .gitignore.and when i asked
can i add this globally?it even suggested further
That's not what I asked about though. I just wanted to see the Claude Code documentation about this.
I am having the same issue. Claude subagents will ignore the .claudeignore to pull sensitive data into the thread
In official docs , I don't see any mention of .claudeignore file being supported
This is supported via third party hook - https://github.com/li-zhixin/claude-ignore
Almost as if this is not a feature of Claude Code
I am experiencing the same issue.
I first heard about the
.claudeignorefile on LinkedIn. I thought I'd search for the official documentation and found nothing except this closed GitHub issue from more than a year ago, where a contributor explicitly suggests using 'deny permission rules':https://github.com/anthropics/claude-code/issues/579
guys are we all hallucinating config files?
Yes
Regardless if this is actually a feature, the file reading is inconsistent as hell. Sometimes the model pops-up dialogs for every single read and sometimes it just uses file-tools to ingest multiple files without asking. File permissions should never be governed by model decisions, but by algorithmic solutions.
I also have the same issue and have seen it a number of times. My
.envis in both.gitignoreand.claudeignorewhen asking Claude Code to tell me what it did earlier in the thread it knows it read the file (I saw it do that too) and it says that the ignore files are not enforced. That seems to be an oversight.<img width="400" height="622" alt="Image" src="https://github.com/user-attachments/assets/672d4a0a-4935-474f-b502-528dd184c1b8" />
I'm leveraging the CLAUDE.md rules section to understand what the file is. Until a fix is in place.
Add the following rule:
``` markdown
...
Rules
.claudeignorefile exists, files and directories listed in the file should be completely ignored. Only ready the.claudeignoreto get that list of files and directories to be ignored and not read. The format of this file follow the same syntax used in the.gitignore....
@ttamg it is not an oversight, the feature doesn't exist and your agent is hallucinating.
I can confirm this bug on macOS with the VS Code extension (Claude Code).
My .claudeignore contained .env, yet Claude read the file without any warning or permission prompt.
I tested this across multiple new sessions and the behavior is consistent: .claudeignore does not prevent the Read tool from accessing listed files.
chmod 600 .env also did not help, as Claude Code runs as the same OS user as the file owner.
This is a serious security issue. Users reasonably expect .claudeignore to act as an access boundary, not just an autocomplete hint. The documentation should clearly state this limitation until it is fixed - or the Read tool should actually respect .claudeignore.
Environment: macOS, VS Code extension, Claude Sonnet 4.6
Move .env outside the project directory (one level up) and start for example dev server with:
npx dotenv-cli -e .env -- yarn --cwd app devThis keeps .env outside Claude Code's working directory entirely, so it won't be accessible regardless of .claudeignore behavior.
For npm users:
npx dotenv-cli -e ../.env -- npm run devIn my opinion it it the only safe solution.
Additional security tips:
OK an update as I did a load more testing and research.
Examples of the sort of preventions you can add to the the .claude/settings.json file to try to stop the tool calls reading your secret files. This is better than what we had but cannot be fully relied upon.
```{
"hooks": {},
"permissions": {
"allow": [],
"deny": [
"Bash(cat .env*)",
"Bash(cat .keys/*)",
"Bash(cat secret)",
"Bash(cat credential)",
"Bash(cat token)",
"Bash(less .env*)",
"Bash(more .env*)",
"Bash(head .env*)",
"Bash(tail .env*)",
"Bash(sed .env)",
"Bash(awk .env)",
"Bash(grep .env)",
"Bash(python .env*)",
"Bash(python open.env)",
"Bash(echo $KEY)",
"Bash(echo $SECRET)",
"Bash(echo $TOKEN)",
"Bash(echo $PASSWORD)",
"Bash(printenv)",
"Bash(env)",
"Bash(set)",
"Read(**/.env)",
"Read(*.pem)",
"Read(*.key)",
"Read(~/.ssh/**)"
]
}
}
Closing for now — inactive for too long. Please open a new issue if this is still relevant.