This error occurs when Git tries to create a file with characters that are illegal on your operating system's filesystem. Windows has strict filename restrictions that Linux and macOS don't, causing cross-platform compatibility issues.
This error occurs when Git attempts to check out or create a file whose name contains characters that are not allowed by your operating system's filesystem. Different operating systems have different rules for what characters are valid in filenames. Windows is the most restrictive, prohibiting these characters in filenames: `\ / : * ? " < > |`. Additionally, Windows reserves certain names like CON, PRN, AUX, NUL, COM1-COM9, and LPT1-LPT9, regardless of extension. Files with trailing spaces or periods are also problematic on Windows. Linux and macOS are much more permissive - they only prohibit `/` (used as path separator) and the null character. This means files created on Linux or macOS with characters like `:` or `|` in their names will cause errors when someone tries to clone or check out the repository on Windows. This is a common issue in cross-platform teams where developers on macOS or Linux create files with characters that work fine on their systems but fail on Windows. The error typically appears during `git clone`, `git checkout`, or `git pull` operations.
First, identify which files contain illegal characters. Git will usually show the filename in the error message:
# Clone or pull to see the error
git clone <repository-url>
# The error will show something like:
# error: unable to create file 'docs/2021:08:05-notes.md': Invalid argument
# error: unable to create file 'data|results.csv': Invalid argumentIf you have access to a Linux/macOS system or WSL:
# List files with Windows-illegal characters
git ls-tree -r HEAD --name-only | grep -E '[<>:"|?*\\]'
# Or find files with specific characters
git ls-tree -r HEAD --name-only | grep ':'
git ls-tree -r HEAD --name-only | grep '|'You can also check without cloning:
# Use git ls-remote and git archive to inspect
git archive --remote=<repository-url> HEAD | tar -t | grep -E '[<>:"|?*\\]'If you need to access the file contents on Windows without renaming the files in the repository, use Git's low-level commands:
# Get the blob hash for a specific file
git rev-parse HEAD:"path/to/file:with:colons.txt"
# Extract the file contents to a valid filename
git show HEAD:"path/to/file:with:colons.txt" > file-with-colons.txt
# Or use cat-file for binary safety
git cat-file -p HEAD:"path/to/file:with:colons.txt" > file-with-colons.txtFor multiple files, you can script this:
# Extract a file with an illegal name to a safe name
git show "HEAD:2021|08|05-data.csv" > 2021-08-05-data.csvThis lets you access the content while avoiding the filename restriction.
If you don't need the files with illegal characters, use sparse checkout to exclude them:
# Initialize sparse checkout
git clone --no-checkout <repository-url>
cd <repository>
git sparse-checkout init --cone
# Include only directories you need
git sparse-checkout set src lib tests
# Or exclude specific problematic directories
git sparse-checkout set '/*' '!problematic-directory/'
# Complete the checkout
git checkout mainFor an existing repository:
# Enable sparse checkout
git sparse-checkout init
# Add patterns to .git/info/sparse-checkout
echo '/*' >> .git/info/sparse-checkout
echo '!path/with/illegal/files/' >> .git/info/sparse-checkout
# Re-read the working tree
git read-tree -mu HEADThis allows you to work with the repository while skipping problematic files.
The proper solution is to rename the files to use cross-platform compatible names. Do this on a system where the files can be checked out (Linux, macOS, or WSL):
# On Linux/macOS or in WSL
cd <repository>
# Rename files with colons to use dashes
git mv "docs/2021:08:05-notes.md" "docs/2021-08-05-notes.md"
# Rename files with pipes
git mv "data|results.csv" "data-results.csv"
# For files with question marks
git mv "FAQ?.md" "FAQ.md"
# Commit the changes
git commit -m "Rename files with Windows-illegal characters"
git pushFor bulk renaming with a script:
# Find and rename files with colons (on Linux/macOS)
find . -name '*:*' -type f | while read file; do
newname=$(echo "$file" | tr ':' '-')
git mv "$file" "$newname"
done
git commit -m "Replace colons with dashes in filenames for Windows compatibility"After pushing these changes, Windows users can clone successfully.
If the problematic files exist throughout the repository history, use git filter-repo to rename them across all commits:
# Install git-filter-repo
pip install git-filter-repo
# Create a fresh clone
git clone --mirror <repository-url> repo-mirror
cd repo-mirror
# Create a filename mapping file (old-name -> new-name)
cat > filename-mappings.txt << 'EOF'
docs/2021:08:05-notes.md==>docs/2021-08-05-notes.md
data|results.csv==>data-results.csv
EOF
# Run filter-repo with path renaming
git filter-repo --path-rename filename-mappings.txt
# Or use a callback for pattern-based renaming
git filter-repo --filename-callback '
return filename.replace(b":", b"-").replace(b"|", b"-")
'
# Push the rewritten history (requires force push)
git push --force --mirror originWarning: This rewrites history. All team members will need to re-clone the repository. Coordinate with your team before doing this.
Git has built-in protections for NTFS filesystem issues. Configure these to catch problems early:
# Enable NTFS protection (default on Windows)
git config --global core.protectNTFS true
# This prevents checking out:
# - Files with Windows-illegal characters
# - Files with reserved names (CON, PRN, etc.)
# - Files with 8.3 name collisions (GIT~1)For macOS/Linux developers creating files that need Windows compatibility:
# Add a pre-commit hook to catch problematic filenames
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# Check for Windows-illegal characters in staged files
illegal_files=$(git diff --cached --name-only | grep -E '[<>:"|?*\]|^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\..*)?$')
if [ -n "$illegal_files" ]; then
echo "Error: Files with Windows-illegal characters detected:"
echo "$illegal_files"
exit 1
fi
EOF
chmod +x .git/hooks/pre-commitYou can also add this as a shared hook in your repository.
If you need to work with a repository containing files with illegal characters on Windows, use WSL:
# Install WSL (in PowerShell as Administrator)
wsl --install
# Open WSL terminal and clone the repository there
wsl
cd ~
git clone <repository-url>
cd <repository>
# Files are stored on the Linux filesystem, not NTFS
# You can work with them normally in WSLImportant considerations:
- Clone into the WSL filesystem (~/ or /home/user/), not /mnt/c/
- Files on /mnt/c/ are still subject to Windows filename restrictions
- Use VS Code with the Remote WSL extension to edit files
- Git operations should be run from within WSL
# Check your current path
pwd
# Good: /home/username/projects/repo
# Bad: /mnt/c/Users/username/projects/repoThis is a sustainable workaround if renaming files is not an option.
As a last resort, you can disable NTFS protection to force the clone, but this has significant drawbacks:
# Disable NTFS protection during clone
git clone -c core.protectNTFS=false <repository-url>
# Or for an existing repository
git config core.protectNTFS false
git checkout .Why this is NOT recommended:
1. Security risk: core.protectNTFS=true was added to address CVE-2019-1353 and CVE-2019-1354
2. Data loss: Files with illegal characters may be created with truncated names or empty content
3. Inconsistent state: Your working directory won't match what Git thinks is there
4. Ongoing issues: Every pull/checkout may have problems
If you must use this approach:
# Re-enable protection after cloning
git config core.protectNTFS true
# Check what files were affected
git statusOnly use this for read-only access to repositories you don't need to modify.
### Cross-Platform Filename Best Practices
To avoid this issue entirely, follow these naming conventions for cross-platform compatibility:
Safe characters: A-Z a-z 0-9 - _ .
Avoid these characters (illegal on Windows):
- \ backslash
- / forward slash (path separator)
- : colon
- * asterisk
- ? question mark
- " double quote
- < less than
- > greater than
- | pipe
Reserved Windows filenames (avoid these regardless of extension):
- CON, PRN, AUX, NUL
- COM1-COM9
- LPT1-LPT9
### Git's Filename Quoting
Git quotes unusual characters in filenames when displaying them:
# If you see quoted paths like this:
# "path/to/file\302\265name.txt"
# Configure Git to show UTF-8 characters directly
git config --global core.quotePath false### Handling Unicode Filenames
Unicode characters themselves are usually fine, but some edge cases cause issues:
# Normalize unicode (macOS NFD vs Windows NFC)
git config --global core.precomposeUnicode true
# This helps with files like "café" vs "café"### CI/CD Considerations
If your CI runs on multiple platforms:
# GitHub Actions example - test filename compatibility
jobs:
check-filenames:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check for Windows-illegal filenames
run: |
if git ls-tree -r HEAD --name-only | grep -qE '[<>:"|?*\\]'; then
echo "Error: Repository contains Windows-illegal filenames"
git ls-tree -r HEAD --name-only | grep -E '[<>:"|?*\\]'
exit 1
fi### Using pre-commit Hooks Repository-Wide
Create a shared pre-commit hook for your team:
# .githooks/pre-commit
#!/bin/bash
# Check for cross-platform filename compatibility
# Windows-illegal characters
if git diff --cached --name-only | grep -qE '[<>:"|?*\\]'; then
echo "ERROR: Staged files contain Windows-illegal characters:"
git diff --cached --name-only | grep -E '[<>:"|?*\\]'
echo ""
echo "Please rename these files before committing."
exit 1
fi
# Windows reserved names
if git diff --cached --name-only | grep -qiE '(^|/)(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\..*)?$'; then
echo "ERROR: Staged files use Windows-reserved names:"
git diff --cached --name-only | grep -iE '(^|/)(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\..*)?$'
exit 1
fi
exit 0Configure Git to use it:
git config core.hooksPath .githooks### NTFS Alternate Data Streams
On Windows, colons have special meaning for NTFS Alternate Data Streams (ADS). A file named file.txt:stream on Unix would attempt to create an ADS on Windows, which may fail or produce unexpected results. This is another reason why colons are prohibited.
### Case Sensitivity Issues
While not directly related to illegal characters, case sensitivity is another cross-platform issue:
# Windows and macOS (HFS+) are case-insensitive
# File.txt and file.txt are the same file
# Linux is case-sensitive
# File.txt and file.txt are different files
# Configure Git for case-insensitive systems
git config core.ignorecase true # Default on Windows/macOSHaving both File.txt and file.txt in a repository will cause similar checkout issues on Windows.
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git