KhueApps
Home/DevOps/Fix fatal: invalid path on Windows reserved filenames in Git

Fix fatal: invalid path on Windows reserved filenames in Git

Last updated: October 07, 2025

Overview

Windows forbids certain file names and path forms. When a repo contains them, Git on Windows can fail with:

  • fatal: invalid path '...'

Common triggers:

  • Reserved names: CON, PRN, AUX, NUL, COM1–COM9, LPT1–LPT9 (any extension)
  • Invalid characters: < > : " / \ | ? *
  • Trailing space or dot in any path segment
  • Case-only collisions on case-insensitive filesystems (Windows, macOS default)
  • Path length issues (often a different error, but related)

This guide shows how to detect, rename, and, if needed, rewrite history to fix these issues while keeping your team unblocked.

Quickstart (most common fix)

  1. Detect problematic paths:
  • On any OS: use the detector script below.
  1. Rename the files/directories to Windows-safe names:
  • Easiest: perform the rename on Linux/macOS or inside WSL, then push.
  • Or use your Git hosting web UI to rename and commit.
  1. Push the fix and have Windows users fetch/checkout:
  • If the invalid names were only in the latest commit, a normal pull works.
  • If you rewrote history, coordinate a force-push and fresh clones.
  1. Prevent regressions:
  • On Windows: git config --global core.protectNTFS true
  • Add a pre-receive or pre-commit hook to block new invalid paths.

Minimal working example: detect and fix by renaming

The following demonstrates finding a bad file and renaming it to a safe path on a POSIX environment (Linux/macOS/WSL) and pushing the fix.

# Clone the repo that fails on Windows
git clone https://example.com/org/repo.git
cd repo

# 1) Detect invalid paths (see full detector below for more checks)
git ls-files | grep -Ei '(^|/)(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|/|$)'
# Suppose it prints: src/AUX/config.json

# 2) Rename to a safe name
git mv src/AUX src/aux_device

# 3) Commit and push
git commit -m "Rename AUX to aux_device for Windows compatibility"
git push

# Windows users can now pull and checkout successfully

Detect invalid paths (script)

Use this fast detector to list paths that are invalid on Windows.

#!/usr/bin/env bash
set -euo pipefail

regex_reserved='(^|/)(?i:con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|/|$)'
regex_badchars='[<>:"\\|?*]'

problem=0
while IFS= read -r -d '' p; do
  base=$(basename "$p")
  segs_ok=1
  # Check reserved names
  if [[ "$p" =~ $regex_reserved ]]; then echo "RESERVED: $p"; segs_ok=0; fi
  # Check invalid characters
  if [[ "$p" =~ $regex_badchars ]]; then echo "BADCHARS: $p"; segs_ok=0; fi
  # Trailing space or dot in any segment
  IFS='/' read -ra parts <<< "$p"
  for s in "${parts[@]}"; do
    if [[ "$s" =~ [[:space:].]$ ]]; then echo "TRAILING-DOT/SPACE: $p"; segs_ok=0; break; fi
  done
  # Case-collision heuristic (same path differing only by case)
  lower=$(printf %s "$p" | tr '[:upper:]' '[:lower:]')
  echo "$lower" >> .git/.casecheck.tmp
  (( problem |= 1-segs_ok ))
done < <(git ls-files -z)

# Case-collision report
if sort .git/.casecheck.tmp | uniq -d | grep -q .; then
  echo "CASE-COLLISION: multiple entries differ only by case"; sort .git/.casecheck.tmp | uniq -d
  problem=1
fi
rm -f .git/.casecheck.tmp

exit $problem

If it exits nonzero or prints lines, you have paths to fix.

Remedies

1) Rename on a POSIX filesystem (recommended)

  • Use Linux/macOS or WSL (inside the Linux filesystem, not /mnt/c).
  • Perform git mv to safe names, commit, and push.
  • Safe naming tips:
    • Avoid reserved names entirely, even with extensions.
    • Replace invalid characters with hyphens or underscores.
    • Remove trailing dots/spaces; normalize spaces.

Example renames:

git mv "docs/CON.txt" docs/con_device.txt
git mv "src/prn" src/print_port
git mv "models/v1./schema.json" models/v1/schema.json

2) Rename via hosting web UI

  • If you only have Windows, use GitHub/GitLab/Bitbucket’s web editor to rename and commit.
  • Then pull on Windows.

3) Temporarily exclude bad paths with sparse-checkout

If you must proceed on Windows before fixing upstream:

git clone --no-checkout https://example.com/org/repo.git
cd repo
git sparse-checkout init --cone
# Exclude known-bad directories or files
echo 'bad/dir/' >> .git/info/sparse-checkout
echo '!bad/dir/' >> .git/info/sparse-checkout
# Or: git sparse-checkout set path/you/need
git checkout

Note: This avoids checking out problematic paths but does not fix the repo.

4) Case-only renames on Windows

Windows is case-insensitive. Do a two-step rename:

git mv File.txt file.tmp && git commit -m "temp rename"
git mv file.tmp file.txt && git commit -m "final case rename"

Or perform the single rename on a POSIX system.

5) Path length issues

If the error is actually about long paths, enable long paths support:

# Windows Git
git config --global core.longpaths true

You may also need OS-level long path support enabled. Shorten long directory names when possible.

Rewrite history (if bad names exist in past commits)

If tags/old commits contain invalid paths, Windows users may fail when checking them out. Use git filter-repo to rewrite:

# Install git-filter-repo first, then:
# Rename across history
git filter-repo --path-rename 'legacy/AUX':'legacy/aux_device'

# Or delete an impossible path from history
git filter-repo --path 'bad/CON.txt' --invert-paths

# Force-push and coordinate with the team
git push --force --tags origin main

Caution: History rewrites require everyone to rebase or reclone. Communicate changes and freeze merges during the rewrite.

Prevent regressions

  • On Windows, keep protection on:
git config --global core.protectNTFS true
  • Add a pre-commit or pre-receive hook using the detector to block invalid paths.
  • Document naming rules in CONTRIBUTING.md.

Pitfalls

  • Trailing whitespace/dots may be invisible in code reviews; use the detector.
  • Submodules: fix names in submodules and update the superproject SHA.
  • Archives: old tags may still contain invalid names after a partial fix; consider a history rewrite.
  • WSL: operate inside the Linux filesystem (e.g., /home), not /mnt/c, to avoid Windows filename rules.

Performance notes (Windows)

  • Enable fast index operations:
git config --global core.fscache true
git config --global core.preloadindex true
  • Large history rewrites are I/O bound; run on SSDs and exclude repo paths from real-time antivirus during the operation.
  • Use sparse-checkout or partial clone to limit data while you fix names.

FAQ

Q: Why does my repo work on Linux but fail on Windows? A: Windows forbids certain names/characters and path forms. Git stores paths verbatim; checkout fails when the filesystem rejects them.

Q: Can I keep files named CON if I never develop on Windows? A: Yes, but contributors on Windows will be blocked. Safer to rename for cross-platform compatibility.

Q: Does adding an extension (e.g., CON.txt) make it valid? A: No. Reserved names are invalid even with extensions.

Q: Will core.longpaths fix invalid names? A: No. It only helps with long paths. You must rename invalid files.

Q: Do I have to rewrite history? A: Only if you need Windows users to check out old commits/tags that contain invalid paths. Otherwise, fixing the latest state may be enough.

Series: Git

DevOps