# Limitations of the REST API Fallback in actions/checkout

> Discover the limitations of the REST API fallback in actions/checkout. Learn why it disables Git-LFS, submodules, SSH, and more by downloading a static archive instead of a full Git clone.

- Repository: [GitHub Actions/checkout](https://github.com/actions/checkout)
- Tags: deep-dive
- Published: 2026-08-30

---

**The REST API fallback in actions/checkout disables Git-LFS, submodules, SSH authentication, sparse checkout, and shallow fetch capabilities because it downloads a static repository archive instead of performing a proper Git clone.**

When the `actions/checkout` action runs in a GitHub Actions workflow, it normally relies on the Git command-line client to clone your repository. However, if a suitable Git binary is unavailable on the runner, the action falls back to downloading the repository archive via the GitHub REST API. This fallback path, implemented in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts), imposes strict limitations that can break workflows relying on advanced Git features.

## How the Fallback Mechanism Works

The action attempts to create a Git command manager through `gitCommandManager.createCommandManager` at the start of execution. If this initialization throws an error—indicating Git is not installed or not functional—the code path switches to the REST API fallback. According to the source code in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) (lines 78-90), this switch only occurs when Git is unavailable **and** `lfs: true` is not set in your workflow configuration.

When triggered, the action calls `downloadRepository` from [`src/github-api-helper.ts`](https://github.com/actions/checkout/blob/main/src/github-api-helper.ts) to fetch a compressed archive of the repository at the requested ref. Because this returns a static snapshot rather than a functional Git repository, several Git-specific operations become impossible.

## Critical Limitations When Using the REST API Fallback

### Git-LFS Objects Cannot Be Fetched

**Git-LFS (Large File Storage)** is completely unsupported in REST API fallback mode. If your workflow sets `lfs: true` and the Git command manager cannot be created, the action throws an error immediately (lines 83-92 in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts)). This occurs because LFS objects are stored outside the main repository archive and require Git's LFS extension to fetch them separately.

### Submodule Cloning Is Disabled

**Submodules** are not included in the REST API archive and cannot be initialized without Git. The action explicitly throws an error when `submodules: true` is configured but the fallback path is taken. Each submodule requires its own Git clone operation, which is impossible when downloading a single static archive.

### SSH Authentication Is Not Supported

The REST API download endpoint only accepts HTTP(S) authentication tokens. If your workflow provides an `ssh-key` input while running in fallback mode, the action fails with an authentication error. SSH keys are irrelevant to the archive download endpoint, which requires a valid `authToken` (personal access token or `GITHUB_TOKEN`) passed through HTTP headers.

### Sparse Checkout and Cone Mode Are Unavailable

**Sparse checkout** functionality—configured via the `sparse-checkout` input—is effectively ignored during REST API fallback. The sparse-checkout logic is only applied when a Git command manager exists, as it requires Git to selectively populate the working directory. The archive endpoint always provides the complete repository tree, making selective file retrieval impossible.

### Shallow Fetch and Fetch Depth Are Ignored

The `fetch-depth` parameter has no effect when using the REST API fallback. While Git clones can perform shallow fetches to limit history depth, the archive endpoint provided by GitHub always returns a complete snapshot of the repository at the requested ref. You cannot perform a shallow clone via the REST API.

### Tag Movement Cannot Be Detected

Without Git client capabilities, the action cannot verify that a tag still points to the same commit it referenced when the workflow started. In normal operation, Git can re-fetch tags to ensure they haven't moved. The REST API fallback downloads the archive once and cannot detect if the tag was updated to point to a different commit during the workflow execution.

## Implementation Details

The fallback logic and its constraints are enforced across three key files:

| File | Role |
|------|------|
| **[`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts)** | Decides whether to use Git or fall back to the REST API and enforces input validation |
| **[`src/github-api-helper.ts`](https://github.com/actions/checkout/blob/main/src/github-api-helper.ts)** | Contains the `downloadRepository` helper that performs the archive download via the REST API |
| **[`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts)** | Creates the Git command manager; its failure triggers the fallback logic |

In [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts), lines 78-90 handle the decision to fall back, while lines 83-92 contain the validation logic that throws errors for incompatible inputs like `submodules`, `ssh-key`, or `lfs: true` when Git is unavailable.

## Configuration Examples

### Standard Git Checkout (Full Features Available)

When Git is present on the runner, all features work normally:

```yaml
steps:
  - uses: actions/checkout@v4
    with:
      lfs: true
      submodules: true
      fetch-depth: 1
      sparse-checkout: 'src/**'

```

### REST API Fallback (Restricted Configuration)

When Git is unavailable, you must disable incompatible features:

```yaml
steps:
  - uses: actions/checkout@v4
    with:
      lfs: false
      submodules: false
      ssh-key: ''  # Must not be provided

```

If the runner lacks Git, the above configuration triggers the REST API download path. The action succeeds only when disallowed options are omitted, downloading the full repository archive at the expense of Git-specific functionality.

## Summary

- **No Git-LFS**: Large files stored via LFS cannot be fetched without a Git client.
- **No Submodules**: Submodule initialization requires Git cloning capabilities unavailable in archive downloads.
- **Token-Only Auth**: Only HTTP(S) bearer tokens work; SSH keys cause failures.
- **Full Tree Only**: Sparse checkout patterns are ignored; the complete repository is always downloaded.
- **Complete History**: The `fetch-depth` parameter is ignored; archives contain full snapshots.
- **Static Refs**: Tags cannot be re-verified after download; you get the state at the moment of the API call.

## Frequently Asked Questions

### When does actions/checkout use the REST API fallback instead of Git?

The REST API fallback activates when `gitCommandManager.createCommandManager` throws an error, indicating Git is not installed or not functional on the runner, and when `lfs: true` is not set in the workflow inputs. This logic is implemented in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts).

### Why doesn't the REST API fallback support Git-LFS?

Git-LFS objects are stored separately from the main repository content and require the Git LFS extension to fetch them. The REST API archive endpoint only packages the standard Git tree, omitting LFS pointers and objects, making LFS support impossible without a proper Git installation.

### Can I use sparse checkout with the REST API fallback in actions/checkout?

No. Sparse checkout requires Git to selectively populate the working directory according to specified patterns. Because the REST API fallback downloads a complete archive of the entire repository tree, sparse checkout logic—which resides in the Git command manager—is never applied.

### How do I know if my workflow is using the REST API fallback?

Check your workflow logs for messages indicating the Git command manager failed to initialize or that the action is downloading the repository via the API. If your workflow fails with errors about `submodules`, `ssh-key`, or `lfs` being incompatible with the current environment while running on a minimal container without Git, you are hitting the REST API fallback limitations.