vercel/turborepo · warning

Git download failed: ${formatError(gitError)} Falling back t

Error message

Git download failed:
${formatError(gitError)}
Falling back to downloading the example via tarball.

What it means

downloadAndExtractExample() first tries the fast path: a blobless, sparse, shallow `git clone` of vercel/turborepo followed by `sparse-checkout set examples/<name>` and `checkout`. Any failure in that chain (runGit wraps execFileSync and throws `\`git <subcommand>\` failed`) is caught here, warned about, and the code falls back to streaming the codeload.github.com tarball. The message is informational: it names the git error and states the fallback; only if the tarball download also fails does the operation actually throw.

Source

Thrown at packages/turbo-utils/src/examples.ts:573

      "--no-checkout",
      "--depth",
      "1",
      "--sparse",
      "https://github.com/vercel/turborepo.git",
      tempDir
    ]);

    // Set up sparse checkout for just the example we want
    runGit(["sparse-checkout", "set", `examples/${name}`], tempDir);

    // Checkout the files
    runGit(["checkout"], tempDir);

    // Copy the example files to the root
    const examplePath = join(tempDir, "examples", name);
    cpSync(examplePath, normalizedRoot, { recursive: true });
  } catch (gitError) {
    warn(
      `Git download failed:\n${formatError(gitError)}\n` +
        "Falling back to downloading the example via tarball."
    );
    cleanupCloneDirectory(tempDir);

    await streamingExtract({
      url: "https://codeload.github.com/vercel/turborepo/tar.gz/main",
      root: normalizedRoot,
      strip: 3,
      filter: (p: string, rootPath: string | null) => {
        return p.startsWith(`${rootPath}/examples/${name}/`);
      }
    });

    return;
  }

  // Clean up the temp directory on success

View on GitHub (pinned to f9245100cf)

Solutions

  1. Treat it as benign if the tarball fallback completes — the example is fetched either way; verify the generated files exist.
  2. Install or upgrade git: `apt-get update && apt-get install -y git` (Debian/alpine: `apk add git`), or on macOS `brew install git`; ensure git >= 2.25 for `sparse-checkout set`.
  3. If behind a proxy, configure git explicitly: `git config --global http.proxy $HTTPS_PROXY` (git ignores undici's ProxyAgent path), or allow egress to github.com and objects.githubusercontent.com.
  4. Remove a stale `.turbo-clone-temp` directory in the target root if a previous run was killed mid-clone, then re-run create-turbo.
  5. If both paths fail, debug the tarball URL directly: `curl -fL https://codeload.github.com/vercel/turborepo/tar.gz/main -o /dev/null` to confirm egress.

Example fix

# before: minimal image, git missing -> 'Git download failed' warning
FROM node:22-slim
RUN npx create-turbo@latest

# after: git present, fast path succeeds
FROM node:22-slim
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
RUN npx create-turbo@latest
Defensive patterns

Strategy: validation

Validate before calling

import { execFileSync } from "node:child_process";
function gitFastPathAvailable(): boolean {
  try {
    const out = execFileSync("git", ["--version"], { stdio: ["pipe", "pipe", "pipe"] }).toString();
    const m = out.match(/(\d+)\.(\d+)/); // needs >= 2.25 for `sparse-checkout set`
    return !!m && (+m[1] > 2 || (+m[1] === 2 && +m[2] >= 25));
  } catch {
    return false; // git missing -> expect the warning, tarball fallback will be used
  }
}

Try / catch

// downloadAndExtractExample already catches internally and falls back to the tarball;
// only the fallback itself can throw, so wrap the call and retry on network errors:
try {
  await downloadAndExtractExample(root, exampleName);
} catch (err) {
  if (err instanceof Error && /ENOTFOUND|ETIMEDOUT|ECONNRESET|fetch failed/.test(err.message)) {
    await downloadAndExtractExample(root, exampleName); // one retry for transient egress failure
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: execFileSync('git', ...) fails for any of: git not installed (ENOENT), git older than 2.25 (no `sparse-checkout set`; partial clone `--filter=blob:none` needs >= 2.19), network egress to github.com blocked by a corporate firewall/proxy (git does not honor https_proxy the way undici does here), TLS/credential helper misconfiguration, or a leftover conflict-marked .turbo-clone-temp directory making cpSync fail — e.g. running `create-turbo --example <name>` on a minimal Docker image or locked-down CI runner.

Common situations: `node:<slim>`/alpine Docker images without the git package; CI runners behind an egress proxy that allows HTTPS fetch (so the tarball fallback works) but blocks git's smart HTTP or DNS; ancient git from a distro repo; flaky networks where the clone times out. Users usually see this warning and the scaffold still succeeds via the tarball.

Related errors


AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17). Data as JSON: /api/errors/c7a85eea85a375ff. Report an issue: GitHub.