A TeamCity 2026.1 macOS Build Agent should not enter production because the console says Connected: require Java 21, a non-root service account, an isolated Agent Pool, explicit Xcode routing, workspace separation, reboot recovery, and a real pipeline acceptance test first.

This applies when you are adding iOS or macOS builds to TeamCity, turning a Mac mini into a shared build node, or evaluating several remote Macs for controlled signing and CI capacity.

01

The fast decision: pilot the node or block production access

Use this rule before assigning a release build configuration:

  • If the host runs the required Java 21 runtime, has a complete Xcode installation, and can prove unattended recovery, continue with production acceptance.
  • If the agent is connected but Xcode, signing, or workspace evidence is missing, keep it in a test pool.
  • If the node needs a user login, root access, or manual keychain repair after reboot, do not place it in the release pool.
  • If you lack fixed Mac capacity, start with one isolated remote Mac as a pilot. Expand only after queue, recovery, and pipeline evidence justify another node.

TeamCity On-Premises 2026.1 and TeamCity Cloud 2026.2 must be treated as different product contexts. Cloud documentation can explain Cloud Agent installation and startup concepts, but it does not prove that an On-Premises feature, default, or startup path works identically. Keep the server edition and version in every acceptance record.

Attention: The agent's Java runtime is not automatically the JDK used by your Xcode project, Gradle task, command-line tool, or custom script. Record both values separately.

02

Runtime and host blockers appear before registration

The first failure domain is not Xcode. It is the host baseline. TeamCity 2026.1 requires Java 21 for the relevant server and agent runtime path, so an older JDK can prevent the agent from starting or registering even when macOS itself is healthy. Confirm the requirement against the TeamCity system requirements for the exact release you operate.

Run the smallest useful checks under the intended agent account:

java -version
echo "$JAVA_HOME"
uname -m
sw_vers

The output must be retained with the host asset record. java -version validates the runtime visible to that shell. JAVA_HOME shows what scripts may select. uname -m helps identify whether the host is Apple Silicon or Intel. sw_vers records the macOS release. These outputs do not replace the TeamCity system requirement review.

An Apple Silicon Mac may still fail a build because the toolchain or dependency assumes another architecture. Do not mark the node compatible from the chip name alone. Test the actual project, package manager, simulator target, native dependency, and signing workflow.

Separate these two decisions:

  • Agent runtime JDK: the Java installation used to run the TeamCity agent.
  • Project build JDK: the Java installation selected by Gradle, Maven, a script, or another build tool inside the job.

A platform team that changes JAVA_HOME globally to fix one project can unintentionally break agent startup. Prefer an explicit service environment for the agent and an explicit project-level selection for the build.

The production account should be a dedicated, non-root macOS user. Administrator privileges may be needed temporarily for tasks such as installing Xcode, accepting license terms, creating directories, installing a launch definition, or changing ownership. The running agent should not retain root privileges merely because initialization was easier that way.

Check these ownership boundaries before registration:

  1. The agent installation directory belongs to the service account.
  2. The checkout and temporary build directories are writable by that account.
  3. Signing material is not readable by unrelated local users.
  4. Administrative installation artifacts are not used as the runtime identity.
  5. The account can invoke Xcode without an interactive administrator prompt.

If any check fails, fix the host baseline before investigating TeamCity authorization. Otherwise, later failures become difficult to attribute.

03

Registration proves communication, not build readiness

A macOS agent normally initiates communication with the TeamCity server. That model makes outbound DNS, proxy, TLS inspection, firewall policy, and the configured server URL part of the build design. The TeamCity quick setup guide describes the connection and registration flow, while the Agent configuration documentation covers the configuration fields that control installation and connection.

Keep these artifacts together:

  • The exact serverUrl used by the agent.
  • The authorization token or registration state, stored through your approved secret process.
  • The fixed agent name.
  • The agent log showing connection attempts and registration results.
  • The server-side authorization status.
  • Proxy settings and a test showing that the node can reach the required endpoint.

Do not rely on a browser test from an administrator workstation. The relevant test runs from the Mac, under the network path and account used by the agent. A reverse proxy can accept a browser request while blocking or rewriting the long-lived agent connection. TLS termination can also create certificate or hostname failures that look like an authorization problem.

A fixed agent name is useful for capacity records and incident response. It lets you distinguish a replacement host from a reused identity. Do not silently copy a configuration file from another node if it contains an old identity, token, path, or environment assumption. Build a controlled configuration from a documented baseline.

The minimum connection validation has five parts:

  1. Start the agent under the service account.
  2. Confirm the agent log reports the intended server URL.
  3. Confirm the server shows the agent as authorized, not merely discovered.
  4. Submit a harmless test configuration and verify that the node can accept work.
  5. Stop network access or the agent process, restore it, and verify reconnection without manual re-registration.

The fifth check matters because a node that works only after an operator edits its configuration is not operationally ready.

04

Xcode routing must match the task, node, and tool output

An Xcode-capable Mac needs more than Apple's command-line tools. The Apple Xcode command-line tool reference documents command-line tooling, but installing command-line tools alone does not establish that the host has the complete Xcode application required by your iOS or macOS workflow.

Check the active developer directory under the agent account:

xcode-select -p
xcodebuild -version
xcodebuild -showsdks

The TeamCity Xcode build documentation explains the Xcode runner context. Use it with the actual host output, not as a substitute for host validation.

For a single supported Xcode version, keep the path explicit. The selected developer directory, TeamCity build configuration, and project scripts should point to the same installation. Avoid a situation where an administrator's shell uses one Xcode version while the launch service uses another.

For multiple Xcode versions, divide responsibilities:

  • Path to Xcode: identifies the installation that a build should use.
  • xcode-select: controls the active developer directory for commands that rely on the system selection.
  • Agent parameters: advertise a controlled capability, such as a supported Xcode path or version.
  • Agent requirements: prevent a build from selecting a node that lacks the required capability.

TeamCity's Agent Requirements documentation explains the matching model. Your implementation should make the requirement readable in the build configuration and the parameter visible on the agent.

A valid routing test has three matching statements:

  • Task requirement: the build explicitly asks for the required Xcode capability.
  • Node parameter: the selected Mac advertises that capability.
  • Tool output: the build log proves that xcodebuild used the intended version and path.

If any statement differs, routing is unproven. A job can be accepted by an online agent and still fail because the node has only Command Line Tools, an obsolete simulator runtime, an inactive Xcode license state, or a different developer directory.

05

Signing and workspace isolation need an explicit boundary

TeamCity does not make concurrent work on one Mac a complete security sandbox. A shared agent can expose residual files, caches, processes, keychains, logs, or credentials if the build design assumes isolation that the host does not provide.

Use the TeamCity Agent Pool documentation to separate workloads by trust and signing risk. A useful production split is:

  • Untrusted pull requests in a pool with no release credentials.
  • Routine unit tests and simulator jobs on general-purpose nodes.
  • Distribution and notarization tasks on dedicated signing nodes.
  • High-risk projects on dedicated Macs when their code or dependencies cannot be trusted.

This is not only a TeamCity permission decision. It is also a macOS account, filesystem, process, and credential decision.

Review the checkout directory and cleanup policy. Confirm that:

  • Each project receives a predictable workspace boundary.
  • Clean checkout behavior is available for sensitive jobs.
  • Caches do not contain signing files or project secrets.
  • Temporary keychains are created for the job and removed afterward.
  • Keychain search paths do not expose unrelated identities.
  • Build artifacts and logs do not print secrets.
  • Failed jobs receive the same cleanup treatment as successful jobs.

Evidence should include a directory listing before and after the job, the credential or keychain inventory permitted by your policy, and the build log showing cleanup. Do not store private signing keys in a general-purpose workspace simply because the first build succeeds.

A practical acceptance choice is conditional:

  • If the job only compiles trusted code without release credentials, a controlled shared test agent may be acceptable.
  • If the job handles distribution certificates, provisioning profiles, notarization credentials, or untrusted pull requests, use separate pools or dedicated Mac nodes.
  • If policy requires physical or tenant-level separation, do not treat a shared Agent Pool as sufficient isolation.

For a broader operating model, connect this deployment to an enterprise Mac signing and workspace isolation plan. The infrastructure choice should follow the trust boundary, not precede it.

06

FAQ: operational decisions for a production Mac agent

How should automatic startup be validated after a reboot?

Use a dedicated service account and an approved macOS launch mechanism. Validate the entire chain rather than only the process: reboot the host, confirm the agent launches, check the TeamCity log, verify reconnection, invoke Xcode, and test keychain access. TeamCity's Cloud startup documentation is useful reference material for startup properties, but do not infer On-Premises behavior from Cloud defaults. Record whether an interactive login was required.

Why can an agent be online but still reject an Xcode job?

The Connected state primarily indicates that the agent can communicate with the server. The job may still fail an agent requirement or encounter a missing Xcode application, wrong xcode-select path, unavailable simulator, invalid license state, or inaccessible signing identity. Compare the build log, agent parameters, and command output produced under the service account. Fix the failed capability instead of repeatedly reconnecting the agent.

How can different Xcode versions be assigned to different Macs?

Give each node an explicit, controlled capability for its installed Xcode path or version. Add a matching requirement to the build configuration, then verify the selected developer directory and xcodebuild -version in the job. Do not rely on the administrator's default shell selection. If a node supports several installations, make the selection deterministic and prevent release jobs from silently falling back to another version.

What is the safest way to protect signing credentials?

Keep release signing jobs away from untrusted pull requests and general test workloads. Use a dedicated pool or Mac, a temporary keychain, narrowly scoped credentials, controlled checkout paths, and post-build cleanup. Inspect the keychain and workspace after both successful and failed jobs. A successful archive does not prove that credentials were removed or that another project could not read residual files.

Is a remote Mac suitable for TeamCity production workloads?

It can be, provided the remote host passes the same acceptance gates as an owned Mac: runtime baseline, network continuity, Xcode routing, signing isolation, unattended recovery, representative pipelines, and capacity fallback. Start with one isolated pilot node when fixed hardware is unavailable. Move to a larger pool only when queue behavior, replacement procedures, and failure evidence support that decision.

07

Reboot recovery is a production requirement, not a convenience

A remote Mac that needs someone to log in after every restart is not a reliable production build node. The automatic startup design must account for the service user, file ownership, environment variables, launch definition, log location, and the difference between a background service and an application that starts only after an interactive login.

TeamCity's Agent startup properties reference can help you identify startup-related configuration concepts. Apply the documented procedure for your exact TeamCity deployment rather than copying a Cloud workflow into an On-Premises installation.

Test recovery in this order:

  1. Record the agent status and current log timestamp.
  2. Reboot the Mac through the approved remote administration method.
  3. Confirm that the agent starts under the non-root account.
  4. Confirm reconnection and authorization without manual token replacement.
  5. Submit a representative Xcode build.
  6. Verify that the intended developer directory is still active.
  7. Test temporary keychain creation or access.
  8. Confirm cleanup and alert delivery when one recovery step fails.

Keep timestamps, console output, TeamCity logs, and job identifiers. A manual operator workaround belongs in the rollback procedure, not in the definition of normal availability.

If launch configuration ownership is unclear, or if Xcode can run only after a user opens the application, mark the node as not ready for unattended release work. It may remain useful in a development pool while the startup design is corrected.

08

Production acceptance requires a real workload and a fallback

An empty project proves almost nothing about a production Mac build node. Use a representative pull request build, simulator tests, an archive, and a controlled signing task. Include the dependency installation path, cache behavior, artifact upload, and cleanup. The objective is not to publish a benchmark; it is to verify that the exact workload your team pays to run can complete under the intended account and isolation policy.

Your production acceptance record should contain:

  • Host architecture and macOS asset details.
  • Agent runtime JDK and project build JDK.
  • TeamCity server edition and version.
  • Agent name, pool, authorization state, and connection evidence.
  • Xcode path, active developer directory, and tool output.
  • Workspace and keychain cleanup evidence.
  • Reboot and reconnection timestamps.
  • Representative build identifiers and logs.
  • The reason for any rejected or deferred capability.
  • The fallback node or rollback action.

Use this decision tree:

  • If all evidence passes and a replacement node can accept the workload, admit the Mac to the production pool.
  • If builds pass but signing cleanup or reboot recovery fails, keep it in a restricted test pool.
  • If routing is ambiguous across Xcode versions, split the capability into separate pools or dedicated nodes.
  • If queue pressure appears but no capacity record exists, gather workload and wait-time evidence before buying more hardware.
  • If one node is a single point of failure, add a tested fallback before assigning it to release-critical work.

For capacity planning, document the expected build classes, peak submission periods, concurrency policy, and fallback behavior. Do not claim that a Mac can handle a particular workload volume without your own representative records. TeamCity's predefined build parameters can help expose build context in logs and diagnostics, but they do not replace capacity testing.

You can also compare this evidence with a team iOS CI/CD capacity plan before committing to a fixed fleet. Capacity should be expanded when queue impact, recovery requirements, or signing isolation justify it, not simply because another developer requests access.

A local Mac mini has advantages: direct physical access, predictable ownership, and no remote delivery dependency. Its weaknesses are equally concrete: capital expenditure before demand is known, hardware replacement work, limited geographic access, and idle capacity when build demand falls. A remote Mac introduces network dependence and provider-side operational risk, but it can give you a separately managed pilot node without forcing a full hardware purchase before your TeamCity workload is understood.

When you need a controlled pilot, review the available KVMNODE remote Mac options and apply the same acceptance record described above. Choose weekly, monthly, or longer capacity only after the node proves its Xcode route, signing boundary, and reboot recovery against your real pipeline.

Your current approach is not automatically the best long-term option if it relies on one office Mac mini, a manually logged-in desktop, or a shared developer workstation. Those setups commonly create fixed-capacity limits, unclear credential ownership, and recovery delays when the host or assigned employee is unavailable. Renting an isolated Mac through KVMNODE can provide a cleaner pilot path for TeamCity: test the real agent, Xcode, signing, and recovery chain first, then scale capacity when the evidence supports it.