{"record":{"id":"ad1f87e7c4b4ea58","repo":"argoproj/argo-workflows","slug":"failed-to-clone-q-w","errorCode":null,"errorMessage":"failed to clone %q: %w","messagePattern":"failed to clone %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/artifacts/git/git.go","lineNumber":152,"sourceCode":"\t\tlogging.RequireLoggerFromContext(ctx).Info(ctx, \"Cloned an empty repository\")\n\t\tvar initErr error\n\t\tr, initErr = git.PlainInit(path, false)\n\t\tif initErr != nil {\n\t\t\treturn fmt.Errorf(\"failed to plain init: %w\", initErr)\n\t\t}\n\t\tif _, remoteErr := r.CreateRemote(&config.RemoteConfig{Name: git.DefaultRemoteName, URLs: []string{a.Repo}}); remoteErr != nil {\n\t\t\treturn fmt.Errorf(\"failed to create remote %q: %w\", a.Repo, remoteErr)\n\t\t}\n\t\tbranchName := a.Revision\n\t\tif branchName == \"\" {\n\t\t\tbranchName = \"master\"\n\t\t}\n\t\tif err = r.CreateBranch(&config.Branch{Name: branchName, Remote: git.DefaultRemoteName, Merge: plumbing.Master}); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create branch %q: %w\", branchName, err)\n\t\t}\n\t\treturn nil\n\t} else if err != nil {\n\t\treturn fmt.Errorf(\"failed to clone %q: %w\", a.Repo, err)\n\t}\n\tif len(a.Fetch) > 0 {\n\t\trefSpecs := make([]config.RefSpec, len(a.Fetch))\n\t\tfor i, spec := range a.Fetch {\n\t\t\trefSpecs[i] = config.RefSpec(spec)\n\t\t}\n\t\topts := &git.FetchOptions{Auth: auth, RefSpecs: refSpecs, Depth: depth, InsecureSkipTLS: g.InsecureSkipTLS}\n\t\tif validateErr := opts.Validate(); validateErr != nil {\n\t\t\treturn fmt.Errorf(\"failed to validate fetch %v: %w\", refSpecs, validateErr)\n\t\t}\n\t\tif err = r.Fetch(opts); isFetchErr(err) {\n\t\t\treturn fmt.Errorf(\"failed to fetch %v: %w\", refSpecs, err)\n\t\t}\n\t}\n\tw, err := r.Worktree()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get work tree: %w\", err)\n\t}","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/artifacts/git/git.go#L134-L170","documentation":"This is the generic clone-failure wrap at workflow/artifacts/git/git.go:152. When git.PlainClone fails with anything other than transport.ErrEmptyRemoteRepository, Load returns 'failed to clone %q' wrapping the underlying go-git error. The real cause is always in the wrapped error: bad URL, auth failure, unknown revision/branch, TLS problems, or network errors.","triggerScenarios":"git.PlainClone(path, false, cloneOptions) in ArtifactDriver.Load fails for any non-empty-repo reason: unreachable host, authentication rejected (SSH key/HTTPS token), repository not found, TLS certificate verification failure, or the target path already containing a non-empty git repository.","commonSituations":"Wrong or renamed repo URL in the workflow spec; missing or expired git credentials (sshPrivateKey secret, HTTPS token); private repos without credentials; self-signed/ corporate CA certificates without insecureSkipTLS or the CA mounted; Azure DevOps repos hitting go-git capability issues; shallow depth=0 combined with unsupported refs.","solutions":["Read the wrapped inner error in the message — it names the actual cause (auth, not-found, TLS, network) and fixes differ per cause.","For auth errors: verify the git secret (ssh-key format includes the 'PRIVATE KEY' header, correct username for HTTPS tokens) and that the secret is referenced correctly in the artifact.","For not-found errors: test the URL with 'git ls-remote <url>' from an environment with the same credentials; fix typos or org renames.","For TLS errors: set insecureSkipTLS: true (non-prod) or mount the CA cert into the executor and configure it.","For Azure DevOps: confirm the workaround context — go-git cannot clone Azure DevOps repos while multi_ack capabilities are unsupported; keep the repo URL containing dev.azure.com so the driver applies its capability workaround."],"exampleFix":"// before: artifact failing to authenticate\n- git:\n    repo: https://github.com/my-org/private-repo.git\n// after: supply credentials via secret\n- git:\n    repo: https://github.com/my-org/private-repo.git\n    usernameSecret:\n      name: github-creds\n      key: username\n    passwordSecret:\n      name: github-creds\n      key: token","handlingStrategy":"try-catch","validationCode":"func precheckRepoReachable(repoURL string, creds *GitCreds) error {\n\tctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n\tdefer cancel()\n\ta := &wfv1.Artifact{ArtifactPaths: nil, Git: &wfv1.GitArtifact{Repo: repoURL}}\n\t_ = a\n\trun := exec.CommandContext(ctx, \"git\", \"ls-remote\", repoURL)\n\tif creds != nil {\n\t\trun.Env = append(os.Environ(), creds.Env()...)\n\t}\n\tout, err := run.CombinedOutput()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"repo %s unreachable: %v: %s\", repoURL, err, out)\n\t}\n\treturn nil\n}","typeGuard":"func isAuthErr(err error) bool {\n\tvar ar *transport.AuthError\n\treturn errors.As(err, &ar)\n}\nfunc isNotFoundErr(err error) bool {\n\treturn errors.Is(err, transport.ErrRepositoryNotFound)\n}","tryCatchPattern":"err := artifactDriver.Load(ctx, artifact, path)\nif err != nil && strings.Contains(err.Error(), \"failed to clone\") {\n\tinner := errors.Unwrap(errors.Unwrap(err))\n\tswitch {\n\tcase isAuthErr(inner):\n\t\treturn fmt.Errorf(\"check git credentials/secret: %w\", err)\n\tcase isNotFoundErr(inner):\n\t\treturn fmt.Errorf(\"verify repo URL exists and is accessible: %w\", err)\n\tdefault:\n\t\t// transient network issue: bounded retry\n\t\tfor i := 0; i < 3; i++ {\n\t\t\ttime.Sleep(time.Duration(1<<i) * time.Second)\n\t\t\tif retryErr := artifactDriver.Load(ctx, artifact, path); retryErr == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\treturn err\n\t}\n}","preventionTips":["Verify the repo URL with 'git ls-remote' using the same credentials before deploying the workflow.","Store SSH keys with the full 'BEGIN ... PRIVATE KEY' block in the secret; use correct usernames for HTTPS tokens.","Test against an empty repo beforehand to know whether you will hit the empty-repo fallback vs clone path.","For private CAs, mount the CA and configure it rather than blindly setting insecureSkipTLS.","Watch go-git limitations (Azure DevOps multi_ack, shallow depth quirks) documented in the driver comments."],"tags":["git","go-git","clone","network","authentication"],"backgroundTag":"git-clone-failed","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}