symfony/translation · error · InvalidResourceException

This is not a local file

Error message

This is not a local file "%s".

What it means

IcuDatFileLoader::load() checks stream_is_local($resource.'.dat') and throws InvalidResourceException if the .dat bundle file is not local. Note the check is done on the resource with a '.dat' suffix while the message prints the original resource path. Like all Symfony translation file loaders, only local files are supported.

Solutions

  1. Ensure the .dat resource bundle resides on the local filesystem and pass its local path.
  2. Copy remote bundle files locally (including all related bundle files) before loading.
  3. Check the configured bundle base path for accidental URL/stream-wrapper prefixes.
  4. Write a custom loader that stages remote bundles into a temp directory first.

Example fix

// before
$loader->load('http://cdn.example.com/messages', 'en');
// after
$loader->load('/app/resources/messages', 'en'); // /app/resources/messages.en.dat must exist locally
Defensive patterns

Strategy: validation

Validate before calling

if (!stream_is_local($resource.'.dat')) {
    throw new \InvalidArgumentException("ICU .dat bundle must be local: {$resource}.dat");
}

Type guard

function isLocalDatBundle(string $base): bool { return stream_is_local($base.'.dat'); }

Try / catch

try {
    $catalogue = $loader->load($basePath, $locale);
} catch (Symfony\Component\Translation\Exception\InvalidResourceException $e) {
    // stage remote bundle locally, retry once
}

Prevention

When it happens

Trigger: Calling IcuDatFileLoader::load($resource, $locale, $domain) where $resource.'.dat' resolves to a non-local stream, e.g. 'http://host/bundle' or a remote wrapper path.

Common situations: Loading ICU resource bundles from a remote or non-local source, misconfigured bundle path with a stream wrapper, or passing a URL to the loader.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of symfony/translation@ae9e8a51bc (2026-09-15). Data as JSON: /api/errors/3e4424b8c4ce73a1. Report an issue: GitHub.

Appendix: source

Thrown at Loader/IcuDatFileLoader.php:29

namespace Symfony\Component\Translation\Loader;

use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Translation\Exception\InvalidResourceException;
use Symfony\Component\Translation\Exception\NotFoundResourceException;
use Symfony\Component\Translation\MessageCatalogue;

/**
 * IcuResFileLoader loads translations from a resource bundle.
 *
 * @author stealth35
 */
class IcuDatFileLoader extends IcuResFileLoader
{
    public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue
    {
        if (!stream_is_local($resource.'.dat')) {
            throw new InvalidResourceException(\sprintf('This is not a local file "%s".', $resource));
        }

        if (!file_exists($resource.'.dat')) {
            throw new NotFoundResourceException(\sprintf('File "%s" not found.', $resource));
        }

        try {
            $rb = new \ResourceBundle($locale, $resource);
        } catch (\Exception) {
            $rb = null;
        }

        if (!$rb) {
            throw new InvalidResourceException(\sprintf('Cannot load resource "%s".', $resource));
        } elseif (intl_is_failure($rb->getErrorCode())) {
            throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
        }

View on GitHub (pinned to ae9e8a51bc)