Capacitor Plugin Native Build Failures in Ionic: Diagnostic Guide
When `npx cap sync` succeeds but Xcode or Gradle rejects a Capacitor plugin, use this diagnostic table and ordered checks to find and fix the native integration mismatch.
06 Aug 2025, 23:40 UTC

Recognizable Condition
npx cap sync completes successfully, but the native build fails in Xcode or Android Studio with errors such as Plugin not found, Module not found, or Duplicate class. The JavaScript package installed without issue, yet the native iOS or Android project never registered the plugin.
Capacitor is the native bridge that lets Ionic web code call device APIs through plugins. A plugin has a JavaScript package and a native implementation—Swift or Objective-C for iOS, Kotlin or Java for Android. cap sync copies web assets and updates native configuration, but it does not compile native code, so a clean sync does not guarantee a clean build.
Cause and Diagnostic Table
| Error pattern | Most likely cause | Where to check |
|---|---|---|
| Plugin class not found in native code | Native dependency not installed or linked | ios/App/Podfile and android/build.gradle.kts |
| Duplicate class or method | Multiple plugins pull different versions of the same library | Run ./gradlew app:dependencies in the Android folder |
| Swift module not found | Missing use_frameworks! in the iOS Podfile | Inspect ios/App/Podfile for Swift plugins |
| AndroidX or legacy support error | Plugin references deprecated android.support packages | Search plugin source for import android.support |
Ordered Diagnostic Checks
- Run Capacitor Doctor
Runnpx cap doctorfrom the project root. It reports CLI, Xcode, Android Studio, CocoaPods, and Gradle versions. Note any version mismatch warnings. - Verify plugin versions
Openpackage.json.@capacitor/core,@capacitor/cli,@capacitor/ios, and@capacitor/androidmust share the same major version. Each plugin should match that major version in itspeerDependencies. - Inspect the iOS Podfile
Openios/App/Podfile. If any installed plugin uses Swift, confirmuse_frameworks! :linkage => :staticappears before thetargetblocks. - Check Android Gradle configuration
Openandroid/build.gradle.kts. ConfirmcompileSdkandtargetSdksatisfy the plugin requirements, and look for mixedandroidxand legacycom.android.supportreferences. - Clean and resync
Deleteios/Pods,android/.gradle, andandroid/app/build, then runnpx cap syncagain from the project root. - Inspect resolved dependencies
On iOS, reviewios/Podfile.lock. On Android, runcd android && ./gradlew app:dependencies --configuration debugRuntimeClasspathto locate version conflicts.
Fixes Tied to Findings
- Missing native install
Runnpx cap sync, thencd ios && pod install --repo-updatefor iOS. For Android, runcd android && ./gradlew cleanbefore rebuilding. These commands assume Xcode or Android Studio is installed and that you have normal user permissions;pod installrequires network access to CocoaPods repositories. - Version mismatch
Align the plugin with your Capacitor major version. Example, replacing<plugin>with the plugin name:
Check the plugin'snpm install @capacitor/core@6 @capacitor/<plugin>@6peerDependenciesbefore installing. - Duplicate Android dependencies
Add a resolution strategy inandroid/build.gradle.ktsto force one version. The version below is illustrative; substitute the version identified by the dependency check:
Editing build files is safe here because these are project files, not generated folders.allprojects { configurations.all { resolutionStrategy { force("com.google.firebase:firebase-bom:32.7.0") } } } - iOS bridging issues
Ensureios/App/Podfilecontains:
Then runplatform :ios, '13.0' use_frameworks! :linkage => :staticcd ios && pod install. - AndroidX migration
If a plugin still usesandroid.support, it has not been migrated to AndroidX. Contact the maintainer or fork the plugin and replace those imports withandroidxequivalents.npx cap migratecan help with Capacitor-managed code, but it does not rewrite third-party plugin source.
Escalation Criteria
Escalate to the plugin maintainer or the Capacitor plugins repository when:
- The plugin has no release in 12 or more months and fails on the latest Capacitor, iOS SDK, or Android API level.
npx cap doctorreports no issues, but the native build fails with plugin-specific symbol errors.- Two first-party Capacitor plugins conflict, such as registering the same native service.
- You are blocked in production with no workaround after four hours of diagnosis.
Limitations and Verification
Important limitations:
- Capacitor 6 and later assume Xcode 15 or later and iOS 13 as the minimum deployment target. Older plugins may lack the privacy manifest entries required for App Store submission.
- Android 14 (API 34) enforces stricter foreground service types. Plugins using background location, Bluetooth, or media playback must declare the appropriate
android:foregroundServiceTypeattributes in the manifest. - Never manually edit files in
ios/App/Podsorandroid/app/build/generated. These directories are regenerated duringcap sync, so changes are lost. - Avoid
npm audit fix --force. It can upgrade Capacitor core without updating plugins, creating silent version skew. - Live Reload (
ionic cap run -l --external) bypasses native plugin code. Test plugins on a physical device without the-lflag to verify permissions, background modes, and hardware integration.
Verification Steps
- Run
npx cap doctorand confirm there are no warnings about CLI, Xcode, Android Studio, CocoaPods, or Gradle versions. - Verify in
package.jsonthat@capacitor/core,@capacitor/cli,@capacitor/ios, and@capacitor/androidall use the same major version. - Check
ios/Podfile.lockandandroid/app/build.gradle.ktsfor resolved dependency versions that align with your plugin requirements. - Perform a clean build. From the project root:
npx cap sync && cd ios && xcodebuild -workspace App.xcworkspace -scheme App -configuration Debug -destination 'generic/platform=iOS'. For Android:cd android && ./gradlew assembleDebug. ReplaceAppwith your actual workspace and scheme names. - Test plugin functionality on a physical device rather than a simulator to confirm permissions, background modes, and hardware features work as expected.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.