When This Error Hits
You just upgraded your Flutter dependencies — maybe you ran flutter pub upgrade or bumped a plugin version in pubspec.yaml. Then you build for iOS, run the app, and boom: MissingPluginException when you try to call any platform-specific method (like camera, location, or file picker). The worst part? Android works fine. iOS crashes with a vague error saying the plugin's method channel isn't found.
I've seen this exact scenario dozens of times. It's almost always a mismatch between what Flutter expects and what the iOS native side has registered. The upgrade broke the bridge.
Root Cause (Plain English)
Flutter plugins work through method channels — a Dart side calls a native method on iOS (or Android). When you upgrade a plugin, the Dart side gets the new channel name or method signature. But the iOS side still has the old registration from the previous Podfile.lock and compiled binaries. The new AppDelegate.swift (or Swift AppDelegate in newer Flutter) doesn't include the plugin's generated registration because the cache is stale.
In Flutter 3.x and later, plugins are auto-registered via FlutterPluginRegistrant. If that file is outdated — which happens when you upgrade without a full clean — the native side doesn't know about the plugin. Result: MissingPluginException.
The Fix — Numbered Steps
- Clean everything. Run these commands in your project root:
flutter clean cd ios rm -rf Podfile.lock pod deintegrate pod cache clean --all cd .. flutter pub getThis removes all cached iOS dependency artifacts. Don't skip
pod deintegrate— it removes the Podfile's integration from the Xcode project, forcing a fresh setup. - Reinstall iOS pods. Then run:
cd ios pod install --repo-updateThe
--repo-updateflag forces CocoaPods to refresh its local specs repo. Without it, you might get an older version cached. This step can take a minute. - Rebuild the app. Back in the project root:
flutter runThis regenerates the
FlutterPluginRegistrantinios/Runner/GeneratedPluginRegistrant.swift(or.mif using Objective-C). Open that file after the build — check that your upgraded plugin's class is listed there. If it's missing, something went wrong in step 2. - If that fails, delete DerivedData. Xcode caches old build artifacts there. Run:
rm -rf ~/Library/Developer/Xcode/DerivedDataThen rebuild from scratch with
flutter run. This is nuclear but works when the cache is stubborn. - Check your AppDelegate. In Flutter 3.x+, you should not manually register plugins in
AppDelegate.swift. The generated registrant handles it. If you have custom code likeGeneratedPluginRegistrant.register(with: self), comment it out. Let Flutter's auto-registration do its job. Duplicate registration causes silent failures.
What to Check If It Still Fails
- Plugin compatibility. Some plugins don't support the latest Flutter version yet. Check the plugin's
CHANGELOGor GitHub issues. I've had this with older versions ofurl_launcherandimage_picker. - iOS minimum deployment target. If a newer plugin requires iOS 14+ but your project targets iOS 12, the native code won't compile. Set it in
ios/Podfiletoplatform :ios, '14.0'(or whatever the plugin needs). - Flutter version. Run
flutter --version. If you're on a very old channel (like 2.x), upgrade to at least 3.10. The auto-registration logic changed significantly after 3.0. - Multiple plugins with same channel name. Rare, but possible if you forked a plugin. Check that no two plugins use the same method channel name.
MissingPluginExceptioncan also mean the channel name is already taken by another plugin that didn't register properly.
If you've done all that and it still breaks, open the Xcode project (ios/Runner.xcworkspace) and build from there. Look for build warnings about missing plugin symbols. Usually it's a pod version mismatch — pin the plugin version in pubspec.yaml to the one that worked before the upgrade, then try a different version.