Distribution certificate hasn’t been imported successfully
Distribution certificate with fingerprint ... hasn't been imported successfully The certificate could not be imported into the keychain
The short answer
Check them in this order — the first is the most common by a wide margin.
- The
.p12has no private key in it. Exporting the wrong row in Keychain Access produces a file containing only the certificate, which cannot sign anything. Verify:
You want aopenssl pkcs12 -in dist.p12 -nocerts -passin pass:YOURPASSWORD | head -1BEGIN PRIVATE KEYline. Nothing, or an error, means you exported the certificate alone — go back and export the parent row with the disclosure triangle, which contains both. - The password is wrong or empty. An empty export password is legal and a frequent surprise; try an empty string explicitly before assuming corruption.
- The Apple WWDR intermediate certificate is missing or expired on the machine doing the import, which makes an otherwise valid certificate untrusted. Install the current one from Apple's certificate authority page.
Why this happens
A distribution certificate on its own is a public document. It proves nothing and signs
nothing. What matters is the private key generated alongside it, which never leaves the
machine that created the signing request — and a .p12 is a container meant to
hold both.
Keychain Access presents these as a parent row (the certificate) with a child row (the private key) hidden behind a disclosure triangle. Selecting and exporting the certificate row alone produces a perfectly valid, perfectly useless file: an import succeeds, and signing later fails, which is why the error arrives at a confusing distance from the mistake.
This is also the reason a certificate cannot be meaningfully "downloaded again" from the Apple developer console. What you download there is the public certificate. If the private key is gone — wiped machine, no backup — the certificate is unusable and the only path is to revoke it and issue a new one.
The OpenSSL 3 wrinkle
If you are inspecting the file on a machine with OpenSSL 3 and it fails to read at all,
that may not be the file's fault. Keychain Access still exports using older PKCS#12 ciphers
that OpenSSL 3 disabled by default. Add -legacy:
openssl pkcs12 -in dist.p12 -clcerts -nokeys -legacy -passin pass:YOURPASSWORD
Tools that read these files should try both forms before reporting a problem, because the difference is in the reader, not the certificate.
Keychain state on CI
On a build machine there is a further trap. Importing into the login keychain leaves
codesign waiting on an interactive permission prompt that nobody will ever
answer, so the build appears to hang rather than fail. The correct pattern is a throwaway
keychain, unlocked explicitly, with the partition list set so that codesign may
use the key without prompting — then deleted afterwards.
Catching it before you build
The private-key case is the one worth catching early, because the symptom otherwise appears much later than the mistake. leas doctor opens the .p12 with the password it will actually build with and reports the identity and expiry it found:
▸ iOS ✓ Xcode Xcode 26.6 ✓ Distribution certificate Apple Distribution: Kaya Labs — valid until 2027-09-25 ✓ Provisioning profile "Kaya App Store" · com.kaya.app — valid until 2027-06-01
Set up leas in 10 minutesFree, MIT licensed, and it never receives your signing keys.
If that didn’t fix it
- The import succeeds and signing still fails. That is the missing
private key case — the file imported fine because a certificate alone is valid. Run the
-nocertscheck above. - It works for one teammate and not another. Whoever created the signing
request holds the private key. Everyone else needs the exported
.p12, not the certificate downloaded from the developer console. - The build hangs instead of failing. That is a keychain prompt waiting for a human on a machine with no human. See the keychain note above.