symfony/translation · error · InvalidResourceException

This is not a local file

Error message

This is not a local file "%s".

What it means

FileLoader::load() checks stream_is_local($resource) before doing anything; if the resource is not a local filesystem path/stream it throws InvalidResourceException. The translation file loaders only support local files, not remote URLs or non-local stream wrappers.

Solutions

  1. Download the remote file locally first (copy(), file_get_contents()) and pass the local path to the loader.
  2. Ensure the resource passed to load() is a local path or a local stream (stream_is_local() returns true).
  3. If you must support remote resources, write a custom loader that fetches the content and delegates to loadResource() with a temp file.
  4. Check for accidental 'http://' or other wrappers in the configured translation resource path.

Example fix

// before
$loader->load('https://cdn.example.com/messages.en.xlf', 'en');
// after
$tmp = tempnam(sys_get_temp_dir(), 'xlf_');
file_put_contents($tmp, file_get_contents('https://cdn.example.com/messages.en.xlf'));
$loader->load($tmp, 'en');
Defensive patterns

Strategy: validation

Validate before calling

if (!stream_is_local($resource)) {
    throw new \InvalidArgumentException("Translation resource must be local: $resource");
}

Type guard

function isLocalResource(mixed $r): bool { return is_string($r) && stream_is_local($r); }

Try / catch

try {
    $catalogue = $loader->load($resource, $locale);
} catch (Symfony\Component\Translation\Exception\InvalidResourceException $e) {
    throw new \LogicException('Only local translation files are supported: '.$e->getMessage(), 0, $e);
}

Prevention

When it happens

Trigger: Calling FileLoader::load() (or any subclass: CsvFileLoader, YamlFileLoader, XliffFileLoader, etc.) with a resource such as 'http://example.com/messages.xlf', 'ftp://...', or another non-local stream wrapper.

Common situations: Trying to load translations from a remote URL or cloud-storage wrapper (s3://), configuring a loader with a URL instead of a local path, or passing a resource string fetched from config that points off-machine.

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/1083fbc2ad2e9d47. Report an issue: GitHub.

Appendix: source

Thrown at Loader/FileLoader.php:27

 * file that was distributed with this source code.
 */

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;

/**
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
abstract class FileLoader extends ArrayLoader
{
    public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue
    {
        if (!stream_is_local($resource)) {
            throw new InvalidResourceException(\sprintf('This is not a local file "%s".', $resource));
        }

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

        $messages = $this->loadResource($resource);

        // empty resource
        $messages ??= [];

        // not an array
        if (!\is_array($messages)) {
            throw new InvalidResourceException(\sprintf('Unable to load file "%s".', $resource));
        }

        $catalogue = parent::load($messages, $locale, $domain);

View on GitHub (pinned to ae9e8a51bc)