---
title: "Breaking: #110966 - Remove UTF8filesystem and systemLocale settings"
manual: "TYPO3 Core Changelog"
version: "main"
permalink: "https://docs.typo3.org/permalink/changelog:breaking-110966-1791465024"
source: "Changelog/15.0/Breaking-110966-RemoveUTF8filesystemAndSystemLocaleSettings.rst"
typo3-version: "15.0"
typo3-major: 15
type: "breaking"
issue: 110966
forge: "https://forge.typo3.org/issues/110966"
tags: ["FAL", "LocalConfiguration", "PHP-API", "NotScanned", "ext:core"]
rendered: "2026-10-27T20:58:30+00:00"
---

# Breaking: #110966 - Remove UTF8filesystem and systemLocale settings {#breaking-110966-1791465024}

See [forge#110966](https://forge.typo3.org/issues/110966)

## Description {#description}

The configuration options
`$GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']` and
`$GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']` have been removed.

Both options existed so that PHP string functions process UTF-8 file names
correctly. To achieve that, TYPO3 temporarily switched `LC_CTYPE` to the
configured system locale around calls to `basename()`, `dirname()`,
`pathinfo()` and `escapeshellarg()`.

The PHP manual still describes `basename()` and `dirname()` as
locale aware. The PHP source code shows that this no longer matters for
TYPO3:

-   `dirname()` is implemented by `zend_dirname()`, which searches for
    the directory separator byte by byte. It does not evaluate the locale at
    all.
-   `basename()` is implemented by `php_basename()`. Since PHP 8.1, it
    searches for the directory separator byte by byte as well, as long as the
    current locale is "ASCII compatible". PHP considers a locale ASCII
    compatible if it uses a single-byte encoding (such as `C`,
    `POSIX` or ISO-8859-1) or UTF-8. Only for other multibyte
    encodings, such as Shift-JIS, Big5 or GBK, PHP walks the string character
    by character with `mblen()`. In these encodings, the second byte of a
    character can be `0x5C`, which is the directory separator on Windows.
    In UTF-8, all bytes of a multibyte character are `0x80` or higher, so
    they never match a directory separator.
-   `pathinfo()` is based on these two functions.

This was verified with PHP 8.2, 8.4 and 8.5 on glibc: all three functions
return the same, correct results for UTF-8 paths in the `C`,
`C.UTF-8`, `en_US.UTF-8` and `de_DE.UTF-8` locales.

`escapeshellarg()` is different. Its implementation
`php_escape_shell_arg()` calls `mblen()` for every byte and silently
skips all bytes that are invalid in the current locale. In the `C`
locale of glibc, which is ASCII, every byte of `0x80` or higher is
invalid, so `äöü.txt` turns into `.txt`. The previous code only
prevented this if both options were configured, and EXT:indexed_search
called `escapeshellarg()` directly. PHP-FPM commonly runs in the
`C` locale, for example when started by systemd.

`\TYPO3\CMS\Core\Utility\CommandUtility::escapeShellArgument()` and
`\TYPO3\CMS\Core\Utility\CommandUtility::escapeShellArguments()` now quote
arguments byte by byte, independent of the current locale: the argument is
wrapped in single quotes, and each single quote is replaced by `'\''`.
This is what `escapeshellarg()` does on POSIX systems, without dropping
bytes. On Windows, `escapeshellarg()` is still used. Arguments containing
null bytes are rejected with an `\InvalidArgumentException`. The shell
calls of EXT:indexed_search and of the install tool use these methods as well.

`\TYPO3\CMS\Core\Utility\PathUtility::basename()`,
`\TYPO3\CMS\Core\Utility\PathUtility::dirname()` and
`\TYPO3\CMS\Core\Utility\PathUtility::pathinfo()` no longer change the
locale and have been deprecated, see
[Deprecation: #110966 - PathUtility basename(), dirname(), pathinfo()](https://docs.typo3.org/permalink/changelog:deprecation-110966-1791471928).

File names are always stored with their Unicode characters (normalized to NFC).
The install tool checks for both options have been removed. Both options are
removed from [`config/system/settings.php`](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/Configuration/Typo3ConfVars/Index.html#file-project-config-system-settings-php) automatically when the install
tool is accessed.

## Impact {#impact}

The local driver no longer transliterates non-ASCII characters of uploaded or
renamed files. Before this change, `Übersicht.pdf` was stored as
`Uebersicht.pdf` if `UTF8filesystem` was disabled. It is now stored
as `Übersicht.pdf`. Characters that are not allowed in file names are
still replaced by underscores. Existing files are not renamed.

New installations have enabled `UTF8filesystem` by default since TYPO3
v12, so they already behave this way.

Reading one of the two options from `$GLOBALS['TYPO3_CONF_VARS']` raises
an "Undefined array key" warning.

## Affected installations {#affected-installations}

-   Installations that have `UTF8filesystem` disabled. This is usually the
    case for installations upgraded from TYPO3 v11 or earlier that never changed
    the option.
-   Installations with extensions that read one of the two options.

## Migration {#migration}

Remove any code that reads the two options.

To keep transliterating file names to ASCII, register a listener for
`\TYPO3\CMS\Core\Resource\Event\SanitizeFileNameEvent`:

**EXT:my_extension/Classes/EventListener/AsciiFileName.php**

```php
namespace MyVendor\MyExtension\EventListener;

use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Charset\CharsetConverter;
use TYPO3\CMS\Core\Resource\Event\SanitizeFileNameEvent;

final readonly class AsciiFileName
{
    public function __construct(
        private CharsetConverter $charsetConverter,
    ) {}

    #[AsEventListener]
    public function __invoke(SanitizeFileNameEvent $event): void
    {
        $fileName = $this->charsetConverter->utf8_char_mapping($event->getFileName());
        $event->setFileName((string)preg_replace('/[^.\w-]/', '_', $fileName));
    }
}
```
