Xcode builds hang forever at "Planning"/clang feature-detection on macOS 26.5 — root cause is a pipe-buffer leak

Symptom

Every build — both the Xcode IDE and command-line xcodebuild — hangs indefinitely at "Pre-planning"/"Planning N/M", before any compilation starts. The build log freezes for 40+ minutes with no progress and no error.

Inspecting the stuck processes:

  • The clang feature-detection probes (clang -v -E -dM -c /dev/null) sit at 0% CPU, blocked in write().
  • SWBBuildService is idle in swift_task_asyncMainDrainQueue → mach_msg — it never reads the probe output.

Root cause: collapsed pipe buffers

On this machine, anonymous pipe buffer capacity has dropped to 512 bytes (a healthy macOS pipe starts at 16 KB and expands to 64 KB on demand).

SWBBuildService runs the clang feature-detection probe and reads its ~15 KB of output lazily (via Swift concurrency). With only a 512-byte buffer, the pipe fills instantly, clang's write() blocks forever, and the build deadlocks before it begins.

swift build (SwiftPM) is unaffected because it drains subprocess pipes continuously in small reads — confirming the problem is the pipe buffer size, not the toolchain or compiler.

The key detail — it's progressive, not constant (looks like a kernel pipe-KVA leak)

This is the part that points at a kernel bug rather than a fixed config:

  • Right after a reboot, a fresh os.pipe() measures 65536 bytes, and builds succeed normally.
  • After ~50 minutes of normal build activity, the same measurement has monotonically degraded to 512 bytes, and builds hang again.

So pipe capacity appears to leak down as pipe kernel-virtual-address (KVA) accounting accumulates during use. Notably, kern.ipc.maxpipekva does not exist as a sysctl OID on 26.5, so there's no tunable to raise the pool.

Minimal diagnostic anyone can run

  import os, fcntl, errno
  r, w = os.pipe()
  fcntl.fcntl(w, fcntl.F_SETFL, os.O_NONBLOCK)
  total = 0
  try:
      while True:
          total += os.write(w, b"x" * 256)
  except OSError as e:
      if e.errno != errno.EAGAIN:
          raise
  print("pipe capacity:", total, "bytes")
  Healthy machine: 16384+ (usually 65536). Affected machine: 512. When it reads 512, every xcodebuild will hang.

What did NOT fix it (ruled out)

  • Downgrading Xcode — tested Xcode 26.4.1 (17E202) via DEVELOPER_DIR: hangs identically. The trigger is the OS, not Xcode/Swift.
  • Raising kern.ipc.maxpipekva — the OID doesn't exist on 26.5.
  • Memory pressure (64 GB, 94% free, 0 swap), /etc/sysctl.conf / boot-time overrides, NVRAM boot-args, MDM/configuration profiles (not enrolled), third-party security/AV/DLP software (none installed), the project/packages, derivedData location, user Xcode prefs (clean HOME still hangs), connected devices.
  • File-descriptor exhaustion — only ~87 pipe FDs were open, so it's not a count limit; it's per-pipe capacity.

What does help

  • Reboot restores 64 KB pipes — but only buys ~1 build before they degrade again. Temporary.
  • Full in-place reinstall of macOS 26.5 resets pipe capacity (the incremental OTA may have left the system inconsistent), but the leak recurs with use.
  • Staying on / reverting to macOS 26.4 is the only durable fix found, since 26.5 is the trigger.

Question for Apple / others seeing this

Has anyone else on 26.5 (25F71) confirmed pipe capacity degrading over time with the Python snippet above? This looks like a kernel pipe-KVA accounting leak introduced in 26.5. A separate, smaller issue is that SWBBuildService drains the clang probe pipe lazily, which turns a small pipe buffer into a hard deadlock instead of just slow I/O — a continuous-drain read would make Xcode resilient to it.

Environment

  • Mac Studio (Apple Silicon), 64 GB RAM
  • macOS 26.5 (build 25F71) — problem began immediately after an incremental OTA update from 26.2 → 26.5
  • Xcode 26.5 (also reproduced on Xcode 26.4.1 / 17E202 — see below)

Confirmed on macOS 26.5.1 (25F80) - still present in the .1 update, not just 25F71.

Your snippet returns 512 bytes on a machine that's currently hitting the hang:

pipe capacity: 512 bytes

Same signature you describe: xcodebuild and the IDE both stall at "Planning" before any compilation, with the clang feature-detection probe (clang -v -E -dM /dev/null) blocked in write() against the shrunken pipe.

Two data points that line up with the kernel-leak theory rather than a stuck helper:

  • logout/login restores capacity too, not only a full reboot - it returns to ~64 KB and then degrades again within about one build cycle.
  • Userspace remedies do not help: pkill of the build helpers (SWBBuildService, sourcekit-lsp, SourceKitService, swift-plugin-server), and wiping ModuleCache / DerivedData / SPM caches. The hang also reproduces with the IDE fully closed via plain xcodebuild, so it isn't a hung GUI helper.

So from here it looks macOS-version-bound (26.5.x) rather than Xcode-bound, consistent with your finding that an Xcode downgrade doesn't move it.

This still occurs as of macOS 26.5.2, and I can confirm that a logout/login cycle will reset the pipe capacity. I'm seeing everything else reported here. Some attention from Apple on this would really help since I'm dealing with this daily.

Confirming this on macOS 26.5.2 — and I may have found what was actually eating the pipe budget on my machine: a third-party background agent (Logitech's, in my case), not (only) the kernel itself. Full story below, because the diagnostic path might help others here.

Environment

  • MacBook Pro (M1 Pro), macOS 26.5.2, Xcode 26.6 (17F113)
  • Symptom identical to OP: xcodebuild (and the IDE) hangs at CreateBuildDescription → ExecuteExternalTool clang. Process samples showed the clang feature-detection probe blocked in write() at 0% CPU, SWBBuildService idle in mach_msg, never draining the probe's stdout. The same clang command finished instantly when run standalone in a terminal.

What we ruled out first (several weeks of isolation before finding this thread)

  • Project source: reproduced on a fresh Xcode-generated SwiftUI project and on a completely different repository. Not project-bound.
  • User profile: created a brand-new Standard user (no iCloud, no prior DerivedData, no signing identities). swift test passed (64 tests — SwiftPM drains pipes continuously, matching OP's observation), but xcodebuild hung at the same clang probe. So it was system-wide, not per-user.
  • Xcode itself: clean reinstall of Xcode from Developer Downloads (SHA-256 + signature verified, reboot after). Fixed it temporarily — then the hang returned. Also consistent with OP's finding that the trigger isn't the Xcode version.
  • DerivedData / destinations: fresh DerivedData per run, simulator-by-UUID vs generic destination, CODE_SIGNING_ALLOWED=NO, clean subprocess env — none of it mattered once a session was in the bad state.
  • MDM / EDR / AV: none installed, machine not enrolled.
  • Safe Mode: PASSED consistently (clean user + same checkpoint, ~11s builds). This was the biggest clue that some normal-boot component was involved.
  • App-level A/B/A of running background apps (Ollama, BetterDisplay; Proton VPN and Docker were inactive): quitting and restoring each app individually while the hang was reproducible changed nothing — 2/2 timeouts in every condition. No causal evidence at the app-quit level.
  • One more data point: a second machine (iMac M1) on the same macOS 26.5.x builds the same checkpoints fine, repeatedly. Same OS, different installed-software set. That pointed us at a per-machine resident process rather than the OS version alone.

Then we found this thread and ran your snippet

During an active hang:

pipe capacity: 512 bytes

Exact match.

The step that closed it for us: find who's holding the pipes

Instead of only killing build helpers, we inventoried pipe FDs across all processes while the machine was in the degraded state:

sudo lsof | grep PIPE | awk '{print $1}' | sort | uniq -c | sort -rn | head -15

Result on my machine:

1002 Logitech 39 Claude 20 logioptio 20 Google 18 LINE ...

The Logitech agent (Logi Options+) was holding 1,002 pipe FDs — ~25x more than the next process. Classic accumulating leak: it apparently creates pipes continuously (device polling / reconnects?) and never releases them.

Causal A/B, no reboot and no logout:

  1. Measured 512 bytes (fail state, builds hanging)
  2. pkill -f -i logi (killed all Logitech agents)
  3. Re-measured: capacity back to healthy (16K+)
  4. xcodebuild succeeded immediately

With Logitech gone, the problem has not returned.

Why I think this fits everyone's observations here

  • Logout/login helping (as JustFoxLabs and tsherb-ig found) is exactly what you'd expect if the depletion is driven by user-level login agents: logout kills them and releases every pipe they hold. Reboot works for the same reason.
  • Progressive degradation over ~50 minutes matches an agent leaking FDs at a steady rate, not only a kernel accounting drift.
  • Killing SWBBuildService / sourcekit-lsp etc. not helping makes sense — the build helpers are victims, not the leaker. The leaker is whatever resident agent is quietly accumulating pipes.
  • OP's ~87 open pipe FDs was measured per-user/process scope, I suspect. A full sudo lsof across all processes is what exposed the outlier for me.

This doesn't rule out that 26.5 changed pipe/KVA accounting in a way that makes the system far more sensitive to such leaks (26.4 may simply tolerate the same leak — which would explain why reverting "fixes" it). But at least on my machine the proximate cause was identifiable, killable, and confirmable without a reboot.

Suggestion for anyone hitting this: while the machine is in the 512-byte state, run the sudo lsof one-liner above and look for a process holding pipes in the hundreds or thousands. Kill just that one, re-run the capacity snippet, and see if it jumps back to 16K+. If we can collect which agents show up across machines (Logitech here — curious what it is on your Mac Studio), that's a much stronger Feedback report for Apple than "kernel leak, cause unknown."

Xcode builds hang forever at "Planning"/clang feature-detection on macOS 26.5 — root cause is a pipe-buffer leak
 
 
Q