LocalePack
ChromeFirefoxEdgeOperaSafariCWS Listing
Vue.jsReact
Next.jsi18nextReact Native
Guides
Home/Guides/default_locale rules
February 21, 2026

default_locale: rules and common errors

default_locale is a single field in manifest.json, but getting it wrong — or omitting it — prevents your extension from loading entirely. This article covers every rule Chrome enforces, the exact error messages you will see, and how to fix each one.

The fundamental rule

Chrome enforces a strict coupling between default_locale and the _locales directory. The rule has two sides:

If _locales/ exists → default_locale is required

Create the _locales directory and omit default_locale and Chrome will refuse to load your extension.

If default_locale is declared → _locales/ must exist

Declare default_locale without creating the _locales folder and you get the same result: the extension fails to load.

If neither exists → fully non-i18n extension

An extension without _locales/ and without default_locale is perfectly valid. It just cannot use chrome.i18n.getMessage() or __MSG_ manifest substitutions.

Error: “default_locale is required”

This is the most common mistake. You add a _locales/ folder with translated files but forget to add default_locale to the manifest.

Chrome DevTools error:

Could not load extension from ‘/path/to/my-extension’.
Manifest file is invalid.
default_locale is required if _locales/ is present.

Fix — add default_locale to manifest.json:

{
  "manifest_version": 3,
  "name": "__MSG_appName__",
  "default_locale": "en"   ← add this
}

The value must be a locale code that has a corresponding folder inside _locales/. If default_locale is "en", there must be a _locales/en/messages.json file.

Error: “_locales/ directory missing”

The opposite mistake: you declare default_locale but either never created _locales/ or accidentally deleted it.

Chrome DevTools error:

Could not load extension from ‘/path/to/my-extension’.
Manifest file is invalid.
_locales directory is missing or inaccessible.

Fix:

# Create the required folder structure
mkdir -p _locales/en

# Then add _locales/en/messages.json with at least one key
echo '{ "appName": { "message": "My Extension" } }' > _locales/en/messages.json

Error: default_locale folder is missing from _locales/

A subtler variant: you have default_locale declared and a _locales/ folder, but the folder for the declared default locale is absent. For example, default_locale is "en" but only _locales/de/ exists.

Could not load extension from ‘/path/to/my-extension’.
Catalog file is missing for locale en.

Fix:

_locales/
├── en/                     ← must match default_locale exactly
│   └── messages.json
└── de/
    └── messages.json

Error: invalid locale code in default_locale

Chrome only accepts locale codes from its approved list. An unrecognised value in default_locale will fail validation.

✗"default_locale": "en-US"
✓"default_locale": "en_US"

Hyphens are not allowed. Chrome uses underscores.

✗"default_locale": "english"
✓"default_locale": "en"

Full language names are not valid. Use the two-letter ISO code.

✗"default_locale": "pt-BR"
✓"default_locale": "pt_BR"

Region codes use underscore, not hyphen.

The folder name inside _locales/ must match default_locale exactly — same casing, same separator. If default_locale is "pt_BR", the folder must be named pt_BR, not pt_br or PT_BR.

What default_locale controls at runtime

Beyond validation, default_locale defines the fallback chain Chrome uses when a locale is unavailable:

User locale: zh_TW (Traditional Chinese)

Chrome lookup order:
  1. _locales/zh_TW/messages.json   ← specific variant
  2. _locales/zh/messages.json      ← parent language (if zh_TW not found)
  3. _locales/en/messages.json      ← default_locale (if zh also not found)

Result: always returns a string, never throws.

This means you can ship a small set of locales and rely on default_locale for the rest. Users whose language is not translated will see your source strings rather than a broken experience.

The fallback only applies at the key level. If a key exists in the target locale file with an empty string value "message": "", Chrome will return an empty string — it will not fall back to the default locale for that key. Always omit untranslated keys entirely, or remove the locale file altogether, rather than leaving empty message strings.

How the Chrome Web Store validates default_locale

The Web Store runs the same manifest validation as Chrome itself when you upload a ZIP. Additionally, it checks that:

  • •default_locale matches a folder in _locales/.
  • •Every _locales/*/messages.json file is valid JSON.
  • •Every key used in __MSG_key__ manifest substitutions exists in the default_locale messages.json.

Upload failures from these checks result in a rejection email with a message like “Your item was found to have errors” and a reference to the manifest field at fault.

Removing i18n from an existing extension

If you decide to remove i18n support from an extension that previously had it, you must remove both sides of the pair together:

# 1. Remove default_locale from manifest.json
{
  "manifest_version": 3,
  "name": "My Extension",   ← plain string, not __MSG_appName__
  "description": "...",
  "version": "1.0.0"
  // no default_locale
}

# 2. Delete the _locales/ directory entirely
rm -rf _locales/
If you remove default_locale but leave the _locales/ folder on disk, Chrome will throw the “default_locale is required” error again. Both must go together.

Quick reference

SituationResult
_locales/ present + default_locale declaredValid — i18n is active
Neither _locales/ nor default_localeValid — non-i18n extension
_locales/ present, default_locale missingError: default_locale is required
default_locale declared, _locales/ missingError: _locales directory missing
default_locale folder absent from _locales/Error: Catalog file is missing for locale {code}
default_locale value uses hyphen (e.g. "en-US")Error: invalid locale code
__MSG_key__ references key missing from default_localeWeb Store rejection / runtime empty string
Translated file has empty message stringReturns empty string — does not fall back

Generate a validated _locales ZIP in minutes

LocalePack validates your source messages.json on upload — catching format errors before translation — and outputs a _locales ZIP with correctly named folders ready to drop into your extension. No manifest errors, no rejected uploads. Pay once, no subscription.

Generate a valid _locales ZIP →
← Back to Guides
LocalePack
GuidesPrivacyTermsSupport

© 2025 LocalePack. All rights reserved.

This project was translated with LocalePack logoLocalePack