# Troubleshooting
Source: https://docs.privacycommand.privacykey.org/troubleshooting

The failures people actually hit, and what to do about each.

## Analysis

**A .dmg won't analyse**

privacycommand mounts the image, analyses the app inside, and unmounts it.
That fails if the image needs a licence agreement accepted, is encrypted, or
contains a `.pkg` installer rather than an app bundle.

Mount it yourself, drag the `.app` out, and analyse that directly.

**The binary summary is nearly empty**

Most likely a stripped release build — symbol names carry much of the
readability in the [call-sites map](https://docs.privacycommand.privacykey.org/binary-and-network). You'll still get
entitlements, signing, SDK fingerprints and strings.

Electron and other runtime-hosted apps are also thin here: the interesting
code is JavaScript inside an asar archive, not the Mach-O.

**Decompilation is unavailable**

Ghidra isn't installed, or privacycommand can't find it. It is optional and
not bundled — everything else works without it.

**No privacy labels appear**

Expected unless the app came from the Mac App Store. Direct downloads and
Homebrew casks have no labels to fetch. See [Privacy labels](https://docs.privacycommand.privacykey.org/privacy-labels).

**Every permission grant reads unknown**

privacycommand couldn't read the TCC databases, which is where the
*granted* axis of the permission matrix comes from. macOS protects them, so
privacycommand itself needs **Full Disk Access** to open them.

The matrix shows a card with a button straight into the right System
Settings pane. Grant it and reopen privacycommand.

Four things go missing, all of them in the permission matrix: the granted
column, any row that exists only because macOS recorded a grant, the
*System access granted* list that flags the inspected app's own Full Disk
Access, Accessibility, Screen Recording or Input Monitoring, and the
**Verdict** column — every row reads *Grant unknown*, which also suppresses
the *Used in binary, not declared* warning even though that one needs no TCC
data. The rest of the static report is unaffected. See
[Requested, granted, used](https://docs.privacycommand.privacykey.org/static-analysis#requested-granted-used).

<a id="the-helper" />

## The helper

**Installation is refused or immediately fails**

If you built from source, the helper's signing team must match the app's —
`CodeSignValidator` rejects the XPC connection otherwise. Check both targets
in **Signing & Capabilities**.

For a release build, this usually means a damaged or partially quarantined
install. Reinstall from a fresh download.

**A source build connects, but the team check never fires**

Expected, and worth knowing about. A helper with no Team Identifier —
unsigned, ad-hoc signed, or Xcode's "Sign to Run Locally" — accepts every
connecting process rather than refusing them. It logs
`No Team ID — accepting connection (dev mode)`; check with
`log show --predicate 'process == "privacycommandHelper"' --last 5m`.

Set a signing team on the helper target to get the real check back. See
[How it protects itself](https://docs.privacycommand.privacykey.org/privileged-helper#how-it-protects-itself).

**Connected, but no file events**

`fs_usage` produces nothing for a process it can't observe. Confirm the run
actually launched the app and that the target isn't a launcher stub that
exits after spawning the real binary elsewhere.

**The helper survived uninstalling the app**

Reinstall privacycommand, uninstall the helper from within it, then remove
the app. Verify with:

```bash
sudo launchctl print system/org.privacykey.privacycommand.HelperTool
```

## Network

**The kill switch won't arm**

It needs the helper installed, and it needs destinations to block — the list
is built from traffic already captured in this run. Let the app talk to
something first.

**Something unrelated lost connectivity**

The kill switch is a **system-wide** `pf` rule, not per-process. If the
inspected app shares a host or CDN with something else, that is blocked too.
Disarm it. See [Network kill switch](https://docs.privacycommand.privacykey.org/kill-switch).

**The app routed around the block**

Blocking is by address. An app that re-resolves a hostname to a different IP
can escape it. For a hard boundary, take the guest offline in
[VM mode](https://docs.privacycommand.privacykey.org/vm-mode).

## auditctl

**preview says Homebrew was not found**

`auditctl preview` looks for `brew` at `$HOMEBREW_PREFIX/bin/brew` first, if
that variable is set, then `/opt/homebrew/bin/brew` and
`/usr/local/bin/brew`. A Homebrew installed somewhere else is invisible to
it unless you point the variable at the prefix:

```bash
HOMEBREW_PREFIX="$(brew --prefix)" swift run -c release auditctl preview
```

Or skip brew entirely with `preview --all-apps`, which reads
`/Applications` and `~/Applications` directly.

**Colour codes in a log file or CI transcript**

Pass `--no-color`, or set `NO_COLOR` in the environment — `auditctl` honours
both. See [auditctl](https://docs.privacycommand.privacykey.org/auditctl).

## Filing a useful issue

Include the privacycommand version, your macOS version and architecture,
whether the helper is installed, and — if you can share it — the
[JSON export](https://docs.privacycommand.privacykey.org/reports). Open it at
[github.com/privacykey/privacycommand/issues](https://github.com/privacykey/privacycommand/issues).

For anything security-sensitive, don't use a public issue — see
[Security](https://docs.privacycommand.privacykey.org/security).
