twigphp/Twig · error · RuntimeError

Unable to convert encoding: required function iconv() does…

Error message

Unable to convert encoding: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.

What it means

convertEncoding() throws this when escape() needs to convert the string to UTF-8 (charset differs from 'UTF-8') but the iconv() function is unavailable because neither ext-iconv nor symfony/polyfill-iconv is installed.

Solutions

  1. Install/enable the iconv extension (php-iconv, docker-php-ext-install iconv, uncomment extension=iconv in php.ini).
  2. Run: composer require symfony/polyfill-iconv.
  3. Ensure templates run with the default UTF-8 charset so no conversion is attempted.
  4. Verify with php -m | grep iconv after deployment.

Example fix

// before
 # docker image without iconv
// after
 RUN docker-php-ext-install iconv
 # or
 composer require symfony/polyfill-iconv
Defensive patterns

Strategy: fallback

Validate before calling

if (!function_exists('iconv') && !extension_loaded('iconv')) {
    // force UTF-8 charset usage or install polyfill before rendering
}

Type guard

function iconvAvailable(): bool { return function_exists('iconv'); }

Try / catch

try {
    $out = $escaper->escape($env, $value, 'html', $charset);
} catch (\Twig\Error\RuntimeError $e) {
    if (str_contains($e->getMessage(), 'iconv() does not exist')) {
        $out = $escaper->escape($env, mb_convert_encoding($value, 'UTF-8', $charset), 'html');
    } else { throw $e; }
}

Prevention

When it happens

Trigger: Calling escape() with $charset !== 'UTF-8' (e.g. 'ISO-8859-1') on a PHP build without ext-iconv and without symfony/polyfill-iconv in the dependency tree.

Common situations: Deploying to a minimal PHP container/Docker image with iconv stripped; a hosting environment with a reduced extension set; composer install without the polyfill.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13). Data as JSON: /api/errors/6a6f12b132a8cd6c. Report an issue: GitHub.

Appendix: source

Thrown at src/Runtime/EscaperRuntime.php:335

            case 'url':
                return rawurlencode($string);

            default:
                if (\array_key_exists($strategy, $this->escapers)) {
                    return $this->escapers[$strategy]($string, $charset);
                }

                $validStrategies = implode('", "', array_merge(['html', 'js', 'url', 'css', 'html_attr', 'html_attr_relaxed'], array_keys($this->escapers)));

                throw new RuntimeError(\sprintf('Invalid escaping strategy "%s" (valid ones: "%s").', $strategy, $validStrategies));
        }
    }

    private function convertEncoding(string $string, string $to, string $from)
    {
        if (!\function_exists('iconv')) {
            throw new RuntimeError('Unable to convert encoding: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.');
        }

        return iconv($from, $to, $string);
    }
}

View on GitHub (pinned to a414c3a491)