# Why did my iOS or Android build fail?

> Paste a failed iOS or Android build log and get the error explained in plain English, with the fix: signing, build numbers, Gradle, Play and App Store uploads.

Usually for one of a few dozen known reasons: signing, version numbers, a Java or CocoaPods mismatch, or a store setting. Paste the failing log from GitHub Actions, Xcode, Gradle or fastlane — or the email from App Store Connect or Google Play — and this explainer names the error, says what it means, and gives the fix. It runs in your browser; nothing is uploaded.

- Tool: Build error explainer. Input: Paste a build log. Free, no signup. Runs entirely in the browser; nothing is uploaded.
- Interactive version: https://capwr.app/free-tools/build-error-explainer
- All free tools: https://capwr.app/free-tools
- Last updated: 2026-10-14

## How it works

The explainer compares your log with the exact messages of 40 common failures, in your browser, and shows each one it finds in the order it appears — what it means and how to fix it. When nothing matches, it pulls out the lines that look like errors and the files they mention, so you know where to look.

## Read a build log in 30 seconds

- Start from the **first** error, not the last line. “Command PhaseScriptExecution failed” and “Process completed with exit code 1” only say that something earlier failed.
- iOS signing errors mention certificates, profiles or teams. They are fixed in your Apple Developer account, not in the code.
- Upload errors — ITMS-… from Apple, “Google Api Error” from Play — happen after a successful build. The binary is fine; version numbers or the store setup are not.

## Errors it recognises

### iOS build

- **[No distribution certificate to sign with](https://capwr.app/free-tools/build-error-explainer/no-signing-certificate).** Xcode needs an Apple Distribution certificate, with its private key, in the keychain of the machine that builds. On a CI runner the keychain starts empty, so the certificate has to be installed during the job. Message: `error: No signing certificate "iOS Distribution" found: No "iOS Distribution" signing certificate matching team ID "ABCDE12345" with a…`
- **[No matching provisioning profile](https://capwr.app/free-tools/build-error-explainer/no-provisioning-profile).** A provisioning profile ties your bundle ID, your certificate and your capabilities together. Xcode found none that matches this bundle ID and certificate. Message: `error: No profiles for 'com.studio.harbor' were found: Xcode couldn't find any iOS App Store provisioning profiles matching…`
- **[No development team selected](https://capwr.app/free-tools/build-error-explainer/requires-a-development-team).** The Xcode project doesn’t say which Apple Developer team signs the app, so Xcode can’t pick a certificate or profile. Message: `error: Signing for "App" requires a development team. Select a development team in the Signing & Capabilities editor. (in target 'App' from…`
- **[The profile is missing a capability](https://capwr.app/free-tools/build-error-explainer/provisioning-profile-missing-capability).** The app asks for a capability — push notifications, Sign in with Apple, associated domains… — that its App ID and provisioning profile don’t include. Message: `error: Provisioning profile "Harbor App Store" doesn't support the Push Notifications capability. (in target 'App' from project 'App')`
- **[CocoaPods is out of sync](https://capwr.app/free-tools/build-error-explainer/podfile-lock-out-of-sync).** The installed pods no longer match Podfile.lock — usually a Capacitor plugin was added or updated without syncing the iOS project. Message: `error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.`
- **[CocoaPods can’t resolve versions](https://capwr.app/free-tools/build-error-explainer/cocoapods-could-not-find-compatible-versions).** Two packages ask for incompatible versions of the same pod — typically plugins written for another Capacitor major version, or an outdated local specs repo. Message: `[!] CocoaPods could not find compatible versions for pod "Capacitor":`
- **[A script inside the Xcode build failed](https://capwr.app/free-tools/build-error-explainer/phasescriptexecution-failed).** One of the project’s script phases exited with an error. This line is only the summary — the real error is printed earlier in the log. Message: `Command PhaseScriptExecution failed with a nonzero exit code`
- **[Native code is missing when linking](https://capwr.app/free-tools/build-error-explainer/undefined-symbols-for-architecture).** The app references native code that wasn’t compiled in — usually a plugin whose iOS part was never installed. Message: `Undefined symbols for architecture arm64:`

### App Store Connect

- **[Built with an iOS SDK that’s too old](https://capwr.app/free-tools/build-error-explainer/itms-90725).** Apple raises the minimum SDK every spring. Builds made with an older Xcode are refused at upload. Message: `ITMS-90725: SDK version issue - This app was built with the iOS 17.5 SDK. All iOS and iPadOS apps must be built with the iOS 18 SDK or…`
- **[This build number was already uploaded](https://capwr.app/free-tools/build-error-explainer/itms-90189).** Each upload for a version needs a new, higher build number (CFBundleVersion). App Store Connect already has one with this number. Message: `ERROR ITMS-90189: "Redundant Binary Upload. You've already uploaded a build with build number '12' for version number '1.2.0'. Make sure you…`
- **[This version number is closed](https://capwr.app/free-tools/build-error-explainer/itms-90186).** The version (like 1.0.0) was already released or approved, so App Store Connect accepts no new builds for it. Message: `ERROR ITMS-90186: "Invalid Pre-Release Train. The train version '1.0.0' is closed for new build submissions"`
- **[A permission message is missing](https://capwr.app/free-tools/build-error-explainer/itms-90683).** The app, or a plugin in it, can use the camera, photos, location or similar, and Info.plist doesn’t say why. Apple requires a sentence for each of those permissions. Message: `ITMS-90683: Missing purpose string in Info.plist - The Info.plist file for the "App.app" bundle should contain a NSCameraUsageDescription…`
- **[The privacy manifest is missing a declaration](https://capwr.app/free-tools/build-error-explainer/itms-91053).** Apple requires a privacy manifest (PrivacyInfo.xcprivacy) declaring why the app uses certain APIs, such as UserDefaults or file timestamps. Capacitor and many plugins use them. Message: `ITMS-91053: Missing API declaration - Your app's code in the "App" file references one or more APIs that require reasons, including the…`
- **[The App Store icon has transparency](https://capwr.app/free-tools/build-error-explainer/itms-90717).** The 1024 × 1024 App Store icon must be fully opaque. A PNG with an alpha channel is refused, even if it looks solid. Message: `ERROR ITMS-90717: "Invalid large app icon. The large app icon in the asset catalog in "App.app" can't be transparent or contain an alpha…`
- **[App Store Connect rejected the API key](https://capwr.app/free-tools/build-error-explainer/app-store-connect-authentication-invalid).** The call was refused: the App Store Connect API key, its Key ID or the Issuer ID is wrong, the key was revoked, or the token expired. Message: `[!] The request could not be completed because: Authentication credentials are missing or invalid. Provide a properly configured and signed…`

### Android build

- **[Android SDK not found](https://capwr.app/free-tools/build-error-explainer/android-sdk-location-not-found).** Gradle doesn’t know where the Android SDK is installed on the build machine. Message: `SDK location not found. Define a valid SDK location with an ANDROID_HOME environment variable or by setting the sdk.dir path in your…`
- **[Wrong Java version for Gradle](https://capwr.app/free-tools/build-error-explainer/android-gradle-plugin-requires-java).** The Android Gradle plugin needs a specific JDK, and newer Capacitor versions need a newer Java than the one installed. Message: `Android Gradle plugin requires Java 17 to run. You are currently using Java 11.`
- **[The Android project was never synced](https://capwr.app/free-tools/build-error-explainer/capacitor-android-project-could-not-be-found).** android/ points at Capacitor’s Gradle modules, but they aren’t there: npx cap sync didn’t run after installing packages. Message: `A problem occurred evaluating project ':app'.`
- **[Android resources failed to compile](https://capwr.app/free-tools/build-error-explainer/android-resource-linking-failed).** An Android resource — usually an icon, a splash image or an XML file — is invalid: a bad file name, broken XML, or a reference to something that doesn’t exist. Message: `Execution failed for task ':app:processReleaseResources'.`
- **[The upload keystore can’t be read](https://capwr.app/free-tools/build-error-explainer/keystore-was-tampered-with-or-password-incorrect).** Release builds are signed with your upload keystore, and Gradle couldn’t open it: wrong path, wrong password or wrong key alias. Message: `com.android.ide.common.signing.KeytoolException: Failed to read key upload from store…`
- **[Two libraries ship the same classes](https://capwr.app/free-tools/build-error-explainer/duplicate-class-found-in-modules).** Two dependencies include the same Java or Kotlin classes — usually different Kotlin standard library versions pulled in by plugins. Message: `Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules kotlin-stdlib-1.8.22 (org.jetbrains.kotlin:kotlin-stdlib:1.8.22)…`
- **[Gradle couldn’t download a dependency](https://capwr.app/free-tools/build-error-explainer/could-not-resolve-gradle-configuration).** A library the app needs wasn’t found in the configured repositories — a wrong version, a missing repository, or a network blip on the runner. Message: `Could not resolve all files for configuration ':app:releaseRuntimeClasspath'.`

### Google Play

- **[This version code was already uploaded](https://capwr.app/free-tools/build-error-explainer/version-code-has-already-been-used).** Every upload to Google Play needs a higher versionCode than any build Play has seen, in every track. Message: `Google Api Error: Invalid request - Version code 12 has already been used.`
- **[Signed with the wrong key](https://capwr.app/free-tools/build-error-explainer/app-bundle-signed-with-the-wrong-key).** Google Play expects uploads signed with the app’s registered upload key. This bundle was signed with a different keystore. Message: `Google Api Error: Invalid request - Your Android App Bundle is signed with the wrong key. Ensure that your App Bundle is signed with the…`
- **[The bundle is signed for debugging](https://capwr.app/free-tools/build-error-explainer/signed-in-debug-mode).** The app bundle was built with the debug signing config. Google Play only accepts release builds signed with your upload key. Message: `Google Api Error: Invalid request - You uploaded an APK or Android App Bundle that was signed in debug mode. You need to sign your APK or…`
- **[Google Play doesn’t know this app yet](https://capwr.app/free-tools/build-error-explainer/package-not-found).** The package name isn’t registered in Play Console for this account. Play’s API can’t create apps: the very first bundle has to be uploaded by hand. Message: `Google Api Error: Invalid request - Package not found: com.studio.harbor.`
- **[The service account can’t upload](https://capwr.app/free-tools/build-error-explainer/caller-does-not-have-permission).** The Google Cloud service account used for uploads wasn’t invited to Play Console, or can’t release this app. Message: `Google Api Error: forbidden: The caller does not have permission`
- **[Target SDK too low for Google Play](https://capwr.app/free-tools/build-error-explainer/must-target-api-level).** Google Play requires apps to target a recent Android API level, and raises the bar every year. Message: `Your app currently targets API level 34 and must target at least API level 35 to ensure it is built on the latest APIs optimized for…`

### Web build

- **[No package-lock.json for npm ci](https://capwr.app/free-tools/build-error-explainer/npm-ci-package-lock-json).** npm ci only installs from a package-lock.json. Projects made in Lovable or Bolt often have a bun.lockb, or no lockfile at all. Message: `npm ERR! The npm ci command can only install with an existing package-lock.json or`
- **[The lockfile doesn’t match package.json](https://capwr.app/free-tools/build-error-explainer/npm-ci-lockfile-out-of-sync).** package.json changed — often edited by an AI builder — without its lockfile, and CI installs refuse to guess. Message: `npm ERR! npm ci can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update…`
- **[Conflicting package versions](https://capwr.app/free-tools/build-error-explainer/npm-eresolve).** Two packages need incompatible versions of a shared dependency (often React or Vite), so npm refuses to install. Message: `npm ERR! code ERESOLVE`
- **[The web build ran out of memory](https://capwr.app/free-tools/build-error-explainer/javascript-heap-out-of-memory).** Node hit its default memory limit while bundling. Big apps and source maps can go over it. Message: `FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory`
- **[A package is imported but not installed](https://capwr.app/free-tools/build-error-explainer/rollup-failed-to-resolve-import).** The code imports a package that isn’t in package.json — common when an AI builder adds a plugin import without the dependency. Message: `[vite]: Rollup failed to resolve import "@capacitor/haptics" from "/home/runner/work/harbor/harbor/src/lib/native.ts".`
- **[TypeScript errors stop the build](https://capwr.app/free-tools/build-error-explainer/typescript-error-ts).** The build script type-checks the code (tsc) and found errors. The bundler alone might build, but the script fails first. Message: `src/pages/Index.tsx(12,7): error TS2322: Type 'string' is not assignable to type 'number'.`
- **[Capacitor can’t find your web build](https://capwr.app/free-tools/build-error-explainer/could-not-find-the-web-assets-directory).** npx cap sync copies the built website into the app, but the webDir folder doesn’t exist — the web build didn’t run, or writes somewhere else. Message: `[error] Could not find the web assets directory: ./dist.`
- **[Capacitor rejected the appId](https://capwr.app/free-tools/build-error-explainer/invalid-app-id).** The appId also has to be a valid Android package name: letters and numbers, dots between parts, no hyphens. Message: `[error] Invalid App ID "com.my-studio.harbor". Must be in Java package form with no dashes (ex: com.example.app)`

### GitHub Actions

- **[GitHub Actions has no minutes left](https://capwr.app/free-tools/build-error-explainer/github-actions-billing).** GitHub didn’t start the job because of a failed payment or a spending limit. On private repositories, macOS runners use minutes ten times faster than Linux ones. Message: `The job was not started because recent account payments have failed or your spending limit needs to be increased. Please check the 'Billing…`
- **[The workflow token lacks a permission](https://capwr.app/free-tools/build-error-explainer/resource-not-accessible-by-integration).** A step tried to write to the repository — a comment, a push, a release — with a GITHUB_TOKEN that only has read access. Message: `HttpError: Resource not accessible by integration`
- **[The job ran too long](https://capwr.app/free-tools/build-error-explainer/github-actions-exceeded-maximum-execution-time).** The job hit its time limit. iOS archives are slow on a fresh runner, and a step waiting for input or a hanging test ends here too. Message: `The job running on runner GitHub Actions 12 has exceeded the maximum execution time of 60 minutes.`
- **[A required secret or input is empty](https://capwr.app/free-tools/build-error-explainer/input-required-and-not-supplied).** An action needed a value, usually from a repository secret, and got nothing: the secret is missing, misspelled, or not available to this workflow. Message: `Error: Input required and not supplied: api-key`

## In CapWrapp

CapWrapp users get this explainer in the app’s Toolbox, and every failed ship has an **Explain with AI** button that reads the whole build log. [Get started free](https://capwr.app/login).

## FAQ

### Which errors does it recognise?

About forty of the most common failures when shipping a web app as an iOS and Android app: Xcode signing and provisioning, CocoaPods, Gradle and Java versions, keystores, App Store Connect ITMS errors, Google Play upload errors, npm installs, and GitHub Actions limits. Each one has its own page with the cause and the fix.

### Is my build log uploaded?

No. The log is matched against the known errors in your browser. Tokens, private keys and long secrets on the lines it shows are hidden.

### What should I paste?

The failing step of the log, from its start to the error — or the whole log. The first real error matters most; “Command PhaseScriptExecution failed” and “exit code 1” are only summaries of an earlier error.

### What if my error is not recognised?

The tool still pulls out the lines that look like errors and the files they mention. CapWrapp users can also open a failed ship in History and choose Explain with AI, which reads the whole build log.

## Related free tools

- [Is your Lovable app ready for the App Store?](https://capwr.app/free-tools/lovable-capacitor-checker) — Paste package.json. See what is set up, what is missing, and get a prompt to paste back into Lovable.
- [Is your Bolt app ready for the App Store?](https://capwr.app/free-tools/bolt-capacitor-checker) — Same checks as the Lovable checker, tuned for Bolt’s Vite projects and Next.js templates.
- [Is your Base44 app ready for the App Store?](https://capwr.app/free-tools/base44-capacitor-checker) — Check a Base44 export: the frontend Capacitor wraps, the backend that stays hosted, and common setup mistakes.
- [Can this GitHub repo become an iPhone and Android app?](https://capwr.app/free-tools/github-repo-checker) — Paste a public repo URL. The same checks as the builder checkers, read straight from GitHub.
- [Capacitor appId and bundle ID validator](https://capwr.app/free-tools/capacitor-config-validator) — Check an appId against Apple and Android rules at once, plus webDir and server.url in capacitor.config.
- [Do you need a Mac to publish an iPhone app?](https://capwr.app/free-tools/do-i-need-a-mac) — Three questions. What you need for TestFlight and Google Play — accounts, costs, and whether a Mac is one of them.
- [Will Apple reject your app as just a website?](https://capwr.app/free-tools/apple-guideline-4-2) — Six questions on Apple’s Minimum Functionality rule — the usual reason wrapped web apps get rejected.
- [Why was my app rejected by Apple or Google Play?](https://capwr.app/free-tools/app-store-rejection-explainer) — Paste the rejection. Get the guideline in plain English, the fix, a reply for App Review, and a prompt for Lovable or Cursor.
- [App icon generator for iPhone and Android](https://capwr.app/free-tools/app-icon-generator) — Drop a logo or type an emoji. Get the iOS 1024 icon, Android adaptive and round icons, and both store icons — in Capacitor’s folders.
- [App Store and Google Play screenshot sizes](https://capwr.app/free-tools/app-store-screenshot-sizes) — Drop screenshots, see which store slots they fit, and export the missing sizes as PNGs both stores accept.
- [Google Play 12 testers, 14 days: when can you publish?](https://capwr.app/free-tools/google-play-12-testers) — Enter your testers and the day the 12th joined. Get the date you can apply for production, a reminder, and draft answers.

## About CapWrapp

CapWrapp turns a web app on GitHub — built with Lovable, Bolt, Base44, Cursor or by hand — into iPhone and Android apps. It adds Capacitor if the repo needs it, signs the builds, and ships them to TestFlight and Google Play from GitHub Actions, with no Mac or Xcode on your side. [Get started free](https://capwr.app/login) · [Lovable to App Store guide](https://capwr.app/guides/lovable-to-app-store)
