docker/compose · error
repository does not contain ref %s, output: %q: %w
Error message
repository does not contain ref %s, output: %q: %w
What it means
While resolving a non-SHA git ref for a remote include, Compose runs `git ls-remote --exit-code <remote> <ref>`. Exit code 2 specifically means the repository is reachable but does not contain the requested ref (branch/tag). The full path and git output are included for context.
Source
Thrown at pkg/remote/git.go:179
if err != nil {
return fmt.Errorf("invalid git subdirectory path: %w", err)
}
if relPath == ".." || strings.HasPrefix(relPath, "../") || strings.HasPrefix(relPath, "..\\") {
return fmt.Errorf("git subdirectory escapes base directory: %s", subDir)
}
return nil
}
func (g gitRemoteLoader) resolveGitRef(ctx context.Context, path string, ref *gitutil.GitRef) error {
if !commitSHA.MatchString(ref.Ref) {
cmd := exec.CommandContext(ctx, "git", "ls-remote", "--exit-code", ref.Remote, ref.Ref)
cmd.Env = g.gitCommandEnv()
out, err := cmd.CombinedOutput()
if err != nil {
if cmd.ProcessState.ExitCode() == 2 {
return fmt.Errorf("repository does not contain ref %s, output: %q: %w", path, string(out), err)
}
return fmt.Errorf("failed to access repository at %s:\n %s", ref.Remote, out)
}
if len(out) < 40 {
return fmt.Errorf("unexpected git command output: %q", string(out))
}
sha := string(out[:40])
if !commitSHA.MatchString(sha) {
return fmt.Errorf("invalid commit sha %q", sha)
}
ref.Ref = sha
}
return nil
}
func (g gitRemoteLoader) checkout(ctx context.Context, path string, ref *gitutil.GitRef) error {
err := os.MkdirAll(path, 0o700)
if err != nil {View on GitHub (pinned to ddc4b044b6)
Solutions
- Check available refs: `git ls-remote <remote>` and copy the exact branch/tag name
- Pin to a full 40-char commit SHA, which skips ls-remote resolution entirely
- If the repo is private, verify credentials — hidden refs can look like missing refs
Example fix
# before include: - path: git://github.com/org/repo.git#feat-new-ui # after (branch was renamed) include: - path: git://github.com/org/repo.git#feat/ui
Defensive patterns
Strategy: validation
Validate before calling
# verify the ref exists before running compose (fast preflight)
remote='https://github.com/org/repo.git'; ref='feature-branch'
git ls-remote --exit-code "$remote" "$ref" >/dev/null || { echo "ref $ref missing in $remote" >&2; exit 1; }
docker compose -f compose.yaml config Prevention
- Pin production includes to full 40-char commit SHAs — resolution is skipped and refs can't dangle
- Add a CI step that ls-remotes every branch/tag referenced by git:// includes
When it happens
Trigger: Including `git://host/repo.git#feature-branch` where that branch doesn't exist (renamed, deleted, typo), or a tag that was never pushed. The error names the original include path, not just the ref.
Common situations: Branch renamed/merged and deleted upstream; typo'd tag in config; refs existing only in forks; shallow server-side ref filtering (some hosts hide refs behind permissions, in which case git may also report exit 2).
Related errors
- git remote resource is disabled by %q
- COMPOSE_EXPERIMENTAL_GIT_REMOTE environment variable expects
- initializing remote resource cache: %w
- git subdirectory must be relative, got: %s
- git subdirectory path traversal detected: %s
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/4f2a4104988372cf.
Report an issue: GitHub.