← Back to Blog

Fix flutter_localizations intl version solving failed

flutterintlpublocalizationgen-l10n

Fix flutter_localizations intl version solving failed

You upgrade Flutter, run flutter pub get, and pub stops with something like this:

Because every version of flutter_localizations from sdk depends on intl 0.20.2
  and some_date_picker >=2.0.0 depends on intl ^0.19.0,
  flutter_localizations from sdk is incompatible with some_date_picker >=2.0.0.
So, because my_app depends on both flutter_localizations from sdk and
  some_date_picker ^2.1.0, version solving failed.

You can try the following suggestion to make the pubspec resolve:
* Try upgrading your constraint on intl: flutter pub add intl:^0.20.2

This is the most common flutter intl version conflict, and it almost always has the same cause. This post shows how to read that output, how to find the package that pins intl, and three fixes ordered from safest to riskiest.

Why flutter_localizations decides your intl version

flutter_localizations ships inside the Flutter SDK. It isn't downloaded from pub.dev, and its intl constraint is fixed by the Flutter release you have installed. You can't pick a different flutter_localizations version to get a different intl, which is why the error says "every version of flutter_localizations from sdk". From the solver's point of view there is only one version.

The constraint has changed across releases. Here is what packages/flutter_localizations/pubspec.yaml declares at each stable tag:

  • Flutter 3.27 and 3.29: intl: 0.19.0 (exact pin)
  • Flutter 3.32 through 3.44: intl: 0.20.2 (exact pin)
  • Flutter 3.47: intl: ^0.20.3 (any 0.20.x from 0.20.3 up)

The jump from 3.29 to 3.32 is where most people hit this, because intl 0.20 is a new minor version for a 0.x package. Under pub's caret rules, ^0.19.0 means >=0.19.0 <0.20.0, so any package declaring intl: ^0.19.0 simply can't resolve against the intl 0.20 that flutter_localizations requires. Moving to 3.47 can trigger a smaller version of the same problem: a package that pins intl: 0.20.2 exactly now conflicts with ^0.20.3.

Check which constraint your SDK uses:

flutter --version
grep intl "$(dirname "$(dirname "$(which flutter)")")/packages/flutter_localizations/pubspec.yaml"

Read the solver output to find the culprit

Pub explains its reasoning as a chain of "Because ... and ..." statements. Read it top to bottom and look for two things.

  1. The line that mentions flutter_localizations from sdk depends on intl X. That X is the version you have to end up with.
  2. The other half of the same sentence: some_package ... depends on intl Y. That package is the one holding you back.

Sometimes the culprit is your own pubspec. If your pubspec.yaml says intl: ^0.19.0, the output reads my_app depends on intl ^0.19.0, and the fix is a one-line edit.

When the chain is long, or the conflicting package is a transitive dependency, these commands help:

# Which direct dependencies have newer versions, including resolvable ones
flutter pub outdated

# Who depends on what (run on a branch where pub get still works)
flutter pub deps --style=compact

flutter pub outdated is especially useful because it shows the latest version of each package and whether that version is resolvable with your current SDK. If the culprit's latest release supports intl 0.20, you already know which fix to use.

Fix 1 (safest): match the SDK-pinned intl

If your own pubspec.yaml lists intl with an old constraint, update it. The Flutter internationalization docs recommend intl: any next to flutter_localizations, which lets the SDK choose:

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: any

If you'd rather have an explicit range, use what pub suggests for your SDK:

# Flutter 3.32 to 3.44
flutter pub add intl:^0.20.2

# Flutter 3.47
flutter pub add intl:^0.20.3

Then run flutter pub get again. If the only conflict was your own constraint, you're done.

intl 0.20 contains small API changes, so after the bump, run flutter analyze and fix anything it flags in code that calls DateFormat, NumberFormat or Bidi directly.

Fix 2: upgrade the package holding intl back

If the conflict comes from a third-party package, check whether a newer release accepts intl 0.20. Most popular packages widened their constraint soon after Flutter 3.32. Pub can raise the constraint for you:

# Upgrade one package past its current major constraint
flutter pub upgrade --major-versions some_date_picker

# Or upgrade everything that can move
flutter pub upgrade --major-versions

--major-versions rewrites the constraints in pubspec.yaml, so review the diff and read the changelog of anything that crossed a major version before you merge.

If no compatible release exists, look at the package's GitHub issues. Often someone has already opened a PR that widens the range to something like intl: '>=0.19.0 <0.21.0'. You can depend on that fork or branch temporarily with a git: dependency while you wait for a release.

Fix 3 (riskiest): dependency_overrides as a short-term workaround

When a package is abandoned or you need a build today, you can force the version:

dependency_overrides:
  intl: ^0.20.2

This tells the solver to ignore every other package's intl constraint. It works, but it carries real risks:

  • The overridden package was never tested against the new intl. If it uses an API that changed, you get compile errors, or worse, wrong date and number formatting at runtime.
  • Overrides only apply to the root package. If you are writing a package, consumers of it won't see the override, and it won't fix their build.
  • They're easy to forget. Pub does warn you: when overrides are active, pub get and pub upgrade print a warning listing the overridden dependencies, and those packages are marked with ! in the output. That warning becomes noise quickly, and teams learn to ignore it.

Keep overrides out of long-lived branches when you can. One option is a pubspec_overrides.yaml file next to pubspec.yaml, which pub also reads during get and upgrade. Add a comment that links to the upstream issue so someone knows when to remove it.

Confirm your localizations still build

Once flutter pub get succeeds, regenerate your localization code to make sure nothing in the ARB pipeline broke:

flutter pub get
flutter gen-l10n
flutter analyze

A minimal l10n.yaml for current Flutter looks like this:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

If gen-l10n complains about synthetic-package or your imports of package:flutter_gen/gen_l10n/... stop resolving, that's a separate change that tends to show up during the same upgrade. The flutter_gen synthetic package migration guide covers it step by step.

Then do a quick smoke test in code to confirm the generated class and intl formatting agree:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
import 'l10n/app_localizations.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: AppLocalizations.supportedLocales,
      home: Builder(
        builder: (context) {
          final locale = Localizations.localeOf(context).toString();
          final today = DateFormat.yMMMMd(locale).format(DateTime.now());
          return Scaffold(body: Center(child: Text(today)));
        },
      ),
    );
  }
}

If that renders a correctly formatted date in each supported locale, your intl bump and generated code are consistent.

Keep the ARB side clean while you're at it

An SDK upgrade is a good moment to check that your translations are healthy too. Errors in ARB files, especially ICU plurals, surface as gen-l10n failures that look like build problems. The FlutterLocalisation ARB editor lets you edit app_<locale>.arb files in a UI instead of raw JSON, manage translations across all your locales, and flags locales that are missing a plural category the language needs, such as a dropped few or many in Polish or Arabic. For more fixes in this area, browse the Flutter i18n tutorials on the blog.

Try FlutterLocalisation free

Get your dependencies resolving, then stop hand-editing ARB JSON. Try FlutterLocalisation free and manage every locale of your Flutter app in one place.