KhueApps
Home/DevOps/Fixing Git 'No url found for submodule path' Errors

Fixing Git 'No url found for submodule path' Errors

Last updated: October 07, 2025

Overview

Git prints “No url found for submodule path '<path>' in .gitmodules” when a submodule’s path exists in the index (gitlink) but .gitmodules lacks a usable URL mapping. This shows up during clone, checkout, or git submodule update --init --recursive, especially in CI.

This guide (DevOps, Git) shows how to diagnose and fix mapping issues fast.

Quickstart (most cases)

  1. Inspect mappings:
    • View what Git expects:
      git ls-files --stage | grep '^160000' || true
      git submodule status || true
      
    • Check .gitmodules:
      test -f .gitmodules && cat .gitmodules || echo ".gitmodules missing"
      git config -f .gitmodules -l || true
      
  2. Sync config, then init/update:
    git submodule sync --recursive
    git submodule update --init --recursive
    
  3. If it still fails, add the missing mapping and commit it:
    # Replace NAME, PATH, URL with real values
    git config -f .gitmodules submodule.NAME.path PATH
    git config -f .gitmodules submodule.NAME.url URL
    git add .gitmodules
    git commit -m "Fix .gitmodules: add URL for submodule PATH"
    git submodule sync --recursive
    git submodule update --init --recursive
    
  4. One-off CI workaround (if you cannot commit right now):
    # Temporary local fix for this checkout only
    git config submodule.NAME.url URL
    git submodule update --init --recursive
    

Minimal working example (reproduce and fix)

This script creates a repo with a submodule, breaks its URL mapping, shows the error, then fixes it.

set -euxo pipefail
rm -rf /tmp/demo-parent /tmp/demo-lib /tmp/demo-clone || true

# Create a library repo
git init /tmp/demo-lib
cd /tmp/demo-lib
printf 'v1\n' > lib.txt
git add lib.txt
git commit -m "lib: v1"

# Create parent and add submodule
cd /tmp
git init demo-parent
cd demo-parent
mkdir -p lib
git submodule add /tmp/demo-lib lib/demo-lib
git commit -m "add submodule lib/demo-lib"

# Break mapping: remove URL from .gitmodules
git config -f .gitmodules --unset submodule.lib/demo-lib.url || true
cat .gitmodules || true
git add .gitmodules
git commit -m "break: missing URL for lib/demo-lib"

# Clone elsewhere and try to init submodules (will fail)
cd /tmp
git clone /tmp/demo-parent demo-clone
cd demo-clone
set +e
err=$(git submodule update --init --recursive 2>&1) || true
echo "$err" | sed -n '1,5p'
set -e

# Fix by restoring URL mapping and update
LIB_URL=/tmp/demo-lib
NAME=lib/demo-lib
PATH=lib/demo-lib

git config -f .gitmodules submodule."$NAME".path "$PATH"
git config -f .gitmodules submodule."$NAME".url "$LIB_URL"

git add .gitmodules
git commit -m "fix: add URL for $PATH"

git submodule sync --recursive
git submodule update --init --recursive

Diagnose the root cause

  • .gitmodules missing or missing URL:
    • .gitmodules must contain entries:
      • submodule.<name>.path = <path>
      • submodule.<name>.url = <url>
    • Check quickly:
      git config -f .gitmodules --name-only --get-regexp '^submodule\..*\.(path|url)$'
      
  • Path mismatch:
    • The path in .gitmodules must match the path staged as a gitlink:
      git ls-files --stage | awk '$1==160000{print $4}'
      
  • Stale local config:
    • Local .git/config may have outdated submodule.<name>.url. Sync:
      git submodule sync --recursive
      git config -l | grep '^submodule\.' || true
      
  • Removed/renamed submodule:
    • Gitlink exists but mapping removed or path changed.
  • Lost .gitmodules:
    • Recover from history or remote:
      git restore --source=HEAD -- .gitmodules || true
      # or from a remote branch
      git restore --source=origin/MAIN -- .gitmodules || true
      

Fixes by scenario

  1. Add a missing mapping (permanent)

    # Identify the submodule name used in .gitmodules (choose a stable name)
    NAME=components-api
    PATH=lib/components-api
    [email protected]:org/components-api.git
    
    git config -f .gitmodules submodule."$NAME".path "$PATH"
    git config -f .gitmodules submodule."$NAME".url "$URL"
    git add .gitmodules
    git commit -m "submodule($PATH): add URL mapping"
    git submodule sync --recursive
    git submodule update --init --recursive
    
  2. Rename/move a submodule path

    old=lib/old-api
    new=lib/new-api
    name=api
    
    git mv "$old" "$new"
    git config -f .gitmodules submodule."$name".path "$new"
    git add .gitmodules
    git commit -m "submodule($name): move to $new"
    git submodule sync --recursive
    git submodule update --init --recursive
    
  3. Remove a submodule cleanly

    path=lib/unused
    git submodule deinit -f "$path"
    git rm -f "$path"
    rm -rf ".git/modules/$path"
    git config -f .gitmodules --remove-section submodule."$path" || true
    git add .gitmodules || true
    git commit -m "remove submodule $path"
    
  4. Temporary CI fix (no repo write access)

    # If you know the correct URL but cannot change the repo
    git config submodule.NAME.url https://example.com/repo.git
    git submodule update --init --recursive --depth 1 --jobs 8
    
  5. Synchronize stale local config

    git submodule sync --recursive
    git submodule update --init --recursive
    

Common symptoms and quick remedies

SymptomLikely causeQuick fix
No url found for submodule path 'X'Missing submodule.*.urlAdd URL to .gitmodules, commit, sync
No submodule mapping found for path 'X'No entry in .gitmodulesAdd path+url entry or remove gitlink
Submodule path changed but URL ignoredPath in .gitmodules differsUpdate submodule.*.path, move dir, sync

Pitfalls

  • Editing .gitmodules locally but forgetting to commit and push it.
  • Manually moving submodule directories without updating submodule.*.path.
  • Deleting the submodule folder with your OS instead of using git submodule deinit and git rm.
  • Assuming .git/config changes persist for others; only .gitmodules is shared.
  • Relative URLs that no longer resolve after a remote layout change.

Performance notes

  • Speed up initialization in CI:
    git submodule update --init --recursive --depth 1 --jobs 8
    
  • Cache dependencies between builds (runner-specific): use a mirror or --reference to reuse objects.
    git clone --recursive --reference /cache/mirror.git <url> repo
    git submodule update --init --recursive --depth 1 --jobs 8
    
  • Avoid unnecessary recursion when you know submodules don’t have submodules:
    git submodule update --init --depth 1 --jobs 8
    

FAQ

  • What is .gitmodules vs .git/config?
    • .gitmodules is versioned and shared; .git/config is local. Always fix mappings in .gitmodules and commit.
  • How do I find the submodule name?
    • Names are the keys under submodule.<name>.*. List them with:
      git config -f .gitmodules --get-regexp '^submodule\..*\.path$'
      
  • Can I fix without committing?
    • Yes, set git config submodule.NAME.url ... as a temporary workaround. Commit a proper fix later.
  • Does shallow clone cause this error?
    • Not directly. This error is about missing URL mapping, not history depth.
  • How do I recover a deleted .gitmodules?
    • Restore from history or from your remote branch, commit it, then git submodule sync and update.

Series: Git

DevOps