KeyMob
All articles

Why that IPA will not install

3 min readDistributionDevices

Getting a build onto a test device fails in about six distinct ways, and iOS reports most of them with the same unhelpful message. Here is how to tell them apart quickly.

First, know which kind of build you have

Signed for Installs on Notes
Development Devices whose UDID is in the profile The usual case for a team build
Ad Hoc Devices whose UDID is in the profile, up to 100 For a wider test group
Enterprise Any device, after trusting the certificate In-house distribution only
App Store Nothing, directly Signed for store distribution and nothing else

That last row catches people out. An App Store build cannot be sideloaded, ever. If somebody hands you the archive that went to review and asks why it will not install, this is why.

Failure 1: the device is not in the profile

Symptom: fails immediately, generic signature error.

A development or Ad Hoc profile embeds a list of permitted device UDIDs. If the device is not on that list, the install stops before it starts.

Fix: read the device’s UDID, add it to the profile in the developer portal, regenerate the profile, and rebuild. Note rebuild — the profile is embedded in the IPA, so editing it in the portal changes nothing about a build you already have.

Failure 2: the profile has expired

Symptom: identical to failure 1, plus everything else in the fleet stops working on the same day.

Development profiles expire, typically after a year, and certificates expire too. When a whole test fleet stops accepting builds at once, this is almost always it.

Fix: renew, rebuild, redistribute. The tell that it is expiry rather than UDID is that it affects every device at once, including ones that worked yesterday.

Failure 3: not enough storage

Symptom: starts, gets partway, fails.

An install needs room for the package and the expanded app at the same time, so a 200 MB IPA needs considerably more than 200 MB free. On a device with 1 GB left and a big app, this fails intermittently — which is worse than failing consistently, because it looks like a signing problem that comes and goes.

Fix: check free space before blaming anything else. It is a five-second check that saves an hour.

Failure 4: the version number went backwards

Symptom: “a newer version of this app is already installed”.

iOS refuses to downgrade in place. If the device has build 412 and you are installing build 409, nothing will happen until the installed one is removed.

Fix: uninstall first — and export any container data you need before you do, because uninstalling takes it with it.

Failure 5: the developer is not trusted

Symptom: installs fine, then refuses to launch, with a dialog about an untrusted developer.

This is not an install failure at all. The app is on the device; iOS just will not run code signed by a certificate the user has not accepted.

Fix: on the device, Settings → General → VPN & Device Management, find the developer, trust it. Once per certificate per device.

Failure 6: entitlements the profile does not grant

Symptom: fails immediately, and the error mentions entitlements if you are lucky.

The app requests a capability — push, App Groups, HealthKit, associated domains — that the provisioning profile does not include. The signature is valid; the permissions do not match.

Fix: enable the capability on the App ID, regenerate the profile, rebuild.

A diagnostic order that saves time

  1. Free storage. Five seconds, and it is a surprisingly common answer.
  2. Is the device’s UDID in the profile? Read the UDID off the device rather than trusting a spreadsheet.
  3. Has the profile expired? Check the date, and check whether other devices broke at the same time.
  4. Is a newer build already installed? Compare versions before uninstalling anything.
  5. Did it install but refuse to launch? Then it is trust, not signing.
  6. Only then start reading entitlements.

Fleet hygiene

Most of this stops happening if you keep three things current: a list of device UDIDs that actually matches the physical devices, a note of when each profile expires, and a habit of auditing installed profiles when a device joins or leaves the fleet. All three are five-minute jobs that each save a lost afternoon later.