symfony/translation · error · InvalidResourceException
MO stream content has an invalid format.
Error message
MO stream content has an invalid format.
What it means
MoFileLoader reads GNU gettext MO (machine object) files. Before parsing it checks the file is at least MO_HEADER_SIZE bytes; if not, the stream cannot contain a valid MO header and InvalidResourceException is thrown.
Solutions
- Compile the .po catalogues with `msgfmt messages.po -o messages.mo` and deploy the resulting .mo files.
- Check the .mo file size: it must be at least 28 bytes; `ls -l` or `wc -c` will reveal empty/truncated files.
- Re-run the translation build step and verify it exits 0 before packaging artifacts.
- If the file is genuinely corrupt, regenerate it from the .po source or VCS.
Example fix
// before
$loader->load('messages.po', 'en'); // raw PO, not compiled MO
// after
exec('msgfmt messages.po -o messages.mo');
$loader->load('messages.mo', 'en'); Defensive patterns
Strategy: validation
Validate before calling
clearstatcache(true, $file);
if (!is_file($file) || filesize($file) < 28) {
throw new \RuntimeException(sprintf('%s is not a compiled MO file (too small)', $file));
} Try / catch
try {
$catalogue = $loader->load($moFile, $locale);
} catch (InvalidResourceException $e) {
error_log('Invalid MO file: '.$e->getMessage());
$catalogue = new MessageCatalogue($locale);
} Prevention
- Always compile .po to .mo with msgfmt before deploying
- Verify artifact size in your build pipeline
- Never commit zero-byte placeholder .mo files
- Add a file-size sanity check before addResource
When it happens
Trigger: loadResource() on an empty, truncated, or non-MO file smaller than the 28-byte MO header — e.g. passing a .po source file where a compiled .mo is expected, or a zero-byte artifact from a failed msgfmt run.
Common situations: Deploying .po files instead of compiled .mo files, msgfmt failing silently in CI so empty .mo files get committed, incomplete uploads.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- The " " message is defined both with and without a context…
- The Translator does not support the following options
- The file dumper needs a path option.
- Unable to create directory
- No support implemented for dumping XLIFF version
AI-assisted analysis of symfony/translation@ae9e8a51bc (2026-09-15).
Data as JSON: /api/errors/2989a21a47ea0194.
Report an issue: GitHub.
Appendix: source
Thrown at Loader/MoFileLoader.php:49
public const MO_BIG_ENDIAN_MAGIC = 0xDE120495;
/**
* The size of the header of an MO file in bytes.
*/
public const MO_HEADER_SIZE = 28;
/**
* Parses machine object (MO) format, independent of the machine's endian it
* was created on. Both 32bit and 64bit systems are supported.
*/
protected function loadResource(string $resource): array
{
$stream = fopen($resource, 'r');
$stat = fstat($stream);
if ($stat['size'] < self::MO_HEADER_SIZE) {
throw new InvalidResourceException('MO stream content has an invalid format.');
}
$magic = unpack('V1', fread($stream, 4));
$magic = hexdec(substr(dechex(current($magic)), -8));
if (self::MO_LITTLE_ENDIAN_MAGIC == $magic) {
$isBigEndian = false;
} elseif (self::MO_BIG_ENDIAN_MAGIC == $magic) {
$isBigEndian = true;
} else {
throw new InvalidResourceException('MO stream content has an invalid format.');
}
// formatRevision
$this->readLong($stream, $isBigEndian);
$count = $this->readLong($stream, $isBigEndian);
$offsetId = $this->readLong($stream, $isBigEndian);
$offsetTranslated = $this->readLong($stream, $isBigEndian);
// sizeHashesView on GitHub (pinned to ae9e8a51bc)