If an Xcode 27 remote build cannot fetch a private Swift package, first verify the repository URL, the macOS account running the job, and that account’s credential source; then confirm Package.resolved is present and tracked. Do not put a token in the repository or URL. Xcode Cloud and self-hosted Mac builds use different authorization paths, so follow the one that matches your build environment.

This runbook is for you if a private package resolves locally but fails during a remote Mac iOS build, if you maintain a self-hosted macOS runner, or if you are setting up private dependencies in Xcode Cloud.

Fastest useful distinction: a rejected repository request is not the same problem as an unreachable host, a changed dependency revision, or a Swift compiler error.

Start by locating the first failure

Treat the first failing operation as the diagnostic boundary. A red build status alone does not identify a credential problem. Open the build report or command-line log and find the earliest error related to package resolution, source checkout, or compilation.

For a command-line build, run the same project or workspace and scheme used by the real job, with the same working directory and macOS user. Apple documents xcodebuild -resolvePackageDependencies as a way to resolve a project’s package dependencies separately from the later build; see the Xcode command-line tool reference. Preserve the relevant output, but redact repository paths, usernames, tokens, and any credential-bearing text before sharing it.

<
First useful evidenceLikely fault areaNext check
Repository host cannot be reached or resolvedNetwork, DNS, firewall, or incorrect hostTest connectivity from the runner and verify the configured host
Repository responds with an access or authentication errorURL permissions or credentialsCheck the job’s account and credential source
Package resolves, but the selected revision differs from the expected oneLock file, branch, tag, or resolution stateCompare the checked-out Package.resolved and dependency declaration
Packages resolve, then Swift compilation failsSource or compiler compatibilityInspect the compiler diagnostic; do not treat it as a repository-authentication failure
A timeout, access denial, and missing revision point to different next actions. Keep the original failure log until you have identified which category applies; deleting caches before that point can erase evidence without correcting the cause.

Check the repository address and reachability

Compare the dependency source in the project, Package.swift, and the resolved dependency record. Confirm that the remote job is contacting the intended SSH or HTTPS address, not merely an address that works from your development machine. Apple’s documentation describes the source and requirement information used in a Swift package dependency declaration.

Then test the dimensions separately:

  • Address: Does the remote job use the expected host and repository path?
  • Reachability: Can that runner resolve the host and establish a connection?
  • Repository and reference: Does the repository exist for that account, and does the requested branch, tag, or revision still exist?
  • Authentication: If the server is reachable, does the credential used by the job have permission to read that repository?
For a sanitized SSH example, use a placeholder rather than a real organization, host, or repository:
git ls-remote <sanitized-repository-url> <branch-or-tag>

A successful connection to the host does not prove that the repository path is correct or that the requested reference exists. Likewise, switching from SSH to HTTPS is not a universal authentication fix: it changes the transport and may require a different credential setup. Change the URL only when you have evidence that the configured address is wrong or that your workflow intentionally uses another transport.

Verify which macOS account runs the job

A common difference between a successful local build and a failed remote one is the executing identity. Your interactive account may have a private key loaded in an SSH agent, trusted server host keys, and a Git configuration that the runner account does not have.

Record the account and execution context at the point where the build starts. Check the job definition, runner service configuration, and shell environment. On a self-hosted Mac, run the diagnostic command and the dependency-resolution command as the same user that launches the production build. A test performed in your logged-in desktop session does not prove that a launch agent or CI service can use the same credentials.

<
Credential or settingWhat to verify for the job accountEvidence to retain
SSH private keyThe intended key is readable by the account and not exposed in logsKey identifier or secure-store reference, never key contents
ssh-agentThe job can reach the expected agent and has the required identity loadedSanitized agent status
known_hostsThe account can validate the repository host without an interactive promptSanitized host-key entry or managed trust configuration
Git configurationThe account’s effective settings match the intended transport and hostSelected configuration keys without embedded secrets
HTTPS credentialThe job obtains a scoped credential through its approved secret mechanismSecret reference and access scope, not token value

Do not print environment variables wholesale while debugging. Build environments often contain signing, source-control, or upload credentials unrelated to the failing package request.

The key must also be usable in a non-interactive job. An SSH configuration that relies on a prompt, an agent available only in a terminal session, or a host key accepted only by your desktop account can pass local tests and still fail in CI. If you modify shared Git configuration, record its previous state and limit the change to the required account or host.

Choose the authorization path for the build environment

Do not copy local SSH instructions into Xcode Cloud. Xcode Cloud has a source-control authorization flow for private dependencies. Apple’s instructions for making dependencies available to Xcode Cloud and its source-control setup documentation describe the platform-specific setup. For a connected account, follow Apple’s Xcode Cloud connection steps and verify access using the account and workflow that perform the build.

Self-hosted macOS CI is different. You manage the runner’s macOS identity and its access to the repository. Configure a credential for the build account through your approved secret-management process, and check SSH trust and Git settings for that same account. If Apple’s documentation indicates a system Git configuration is appropriate for your workflow, validate that behavior in the Xcode version and job environment you actually use. Do not assume every Xcode installation or runner uses the same Git behavior.

<
Build environmentAuthorization to checkCommon false assumption
Xcode CloudThe source-control authorization configured for the workflowA local Mac key also grants the hosted workflow access
Self-hosted Mac runnerCredentials and host verification available to the runner’s macOS accountA developer’s interactive terminal proves the runner can authenticate
Local Xcode buildThe logged-in user’s source-control setupLocal success proves the remote build has the same identity and settings
For a self-hosted task, a useful diagnostic is to run package resolution under the runner account and capture only sanitized output. For Xcode Cloud, use the platform’s authorization controls rather than trying to install a local runner’s SSH files into the hosted job.

Confirm the lock file before changing resolution behavior

Inspect Package.resolved in the remote checkout and confirm that the file is in the project location used by your workflow and included in version control. Apple’s Swift package CI guidance explains how resolved package versions support repeatable CI builds. Compare the resolved package identities and revisions with the intended state; do not infer a lock-file problem solely from a fetch failure.

<
Lock-file evidenceWhat it tells youAction
Expected file is present and matches the reviewed changeThe job can use the committed resolution stateContinue investigating access or compilation
File is missing from the checkout or not trackedThe remote job may resolve dependencies without the expected committed stateCheck project placement and version-control status, then commit the intended lock file
File is present but contains an unexpected revisionThe committed dependency state differs from the build expectationReview the change that updated resolution before rebuilding
Resolution succeeds, but compilation failsFetching is no longer the blockerDiagnose the compiler or source error separately
The exact location and behavior can depend on how your project is organized and which Xcode tools invoke resolution. Confirm the file in the actual CI checkout rather than relying on a local path. Avoid forcing automatic resolution as a substitute for checking credentials or version control: it can change dependency selection while leaving the access problem untouched.

Repair credentials without creating a second incident

Before changing a secret, determine where it may have been exposed. Search reviewed configuration and recent logs for credential-bearing URLs, shell tracing, or scripts that echo environment values. Do not paste an actual token, private key, or unredacted remote URL into a build report or support request.

If a secret was committed or written to a log, removing the visible text is not enough. Treat the credential as exposed, revoke or rotate it through the system that issued it, and check whether repository history or retained logs still contain the old value. Limit the replacement credential to the read access needed for package retrieval; do not reuse a broad personal credential when a narrower option is available.

Before removing an SSH key, changing shared Git configuration, or clearing package caches, identify which jobs and projects depend on the current setting. Keep a rollback path that restores the previous non-secret configuration if the change blocks an unrelated build. Cache cleanup is appropriate only when evidence points to stale or inconsistent cached state; it cannot grant repository permission or make an unreachable host available.

Apple’s guidance on common Xcode configuration and build issues can help you separate setup problems from build failures. Use it alongside the actual first error in your job log, not as a reason to apply unrelated cleanup steps.

Re-run the job and record proof of repair

Use this decision checklist before closing the incident:

  • [ ] The failing job’s actual repository URL matches the intended dependency source.
  • [ ] The repository host is reachable from the build environment.
  • [ ] The requested repository and branch, tag, or revision are available.
  • [ ] You know which macOS account executes the self-hosted job, or which Xcode Cloud authorization applies.
  • [ ] The job account can access the required credential without exposing it in output.
  • [ ] SSH host verification and relevant Git settings are available to the job account, when the workflow uses SSH.
  • [ ] Package.resolved is present in the remote checkout and matches the intended dependency state.
  • [ ] The resolution step succeeds before you treat a later Swift compiler error as resolved.
  • [ ] Any exposed secret has been replaced, and the new credential has only the access the build needs.
Re-run dependency resolution from a clean checkout or workspace that reflects the production job’s entry point and account. Keep evidence for three separate outcomes: repository access succeeded, the resolved revisions match the expected lock state, and the final build completed. These checkpoints make the repair reproducible and help you detect whether a later failure is a new compilation issue rather than a return of the fetch problem.

If resolution still fails, compare the failing job with the last successful one: account, credential reference, repository address, and lock-file change. Change one verified cause at a time. That produces a clearer rollback and avoids turning a credential incident into an unexplained dependency update.

FAQ: Private package fetch failures

Why does local resolution work while the remote build fails?

Your local session may have credentials and trusted host keys that the job account lacks. Check the actual remote account and credential source, then test repository access from that context. If the repository is reachable but denies access, investigate authorization; if it cannot be reached, investigate the host, DNS, or network path before changing dependency versions.

How can xcodebuild fetch an SSH dependency on a self-hosted Mac?

Run the resolution command as the same macOS account that runs the production build. Confirm that the account can use its SSH key and agent, validate the host through known_hosts, and read the intended Git configuration. Test with a sanitized repository address and avoid interactive prompts. Keep private key contents and tokens out of shell output and CI logs.

Where should you grant private-package access in Xcode Cloud?

Use the source-control authorization settings documented for Xcode Cloud and the workflow’s connected account. Confirm that this account can read the private repository, then test the workflow itself. A credential configured on a self-hosted Mac does not carry over to Xcode Cloud, so diagnose the hosted authorization path separately from local SSH settings.

What should you do if Package.resolved is absent from the remote checkout?

Confirm that the lock file is in the location used by the project and is tracked in version control. Compare the remote checkout with the dependency state reviewed for the build. If the workflow requires repeatable versions, commit the intended file and rerun resolution. Do not force a fresh automatic resolution to hide a missing file or a separate authentication failure.

If you have confirmed that the repository is reachable, authorization works, and the lock file is correct, but your self-hosted runner still lacks a stable macOS environment, a dedicated remote Mac may simplify account and credential isolation. A general cloud runner can leave you managing host access, persistent SSH state, and macOS-specific setup; buying a Mac avoids remote-host variability but adds hardware ownership and maintenance. Neither option fits every team: if you need local peripherals or sustained, predictable use, an owned Mac may be better. If you only need a separate macOS build environment when required, review MACGPU’s remote Mac options and the available Mac plans, then compare their access and delivery details with your runner requirements before choosing.