PHPOffice/PHPWord · error · Exception

Unable to convert text to UTF-8

Error message

Unable to convert text to UTF-8

What it means

Shared\Text::toUTF8() converts non-UTF-8 (assumed ISO-8859-1) text using mb_convert_encoding or, on older setups, utf8_encode. It throws Exception if the conversion returns false, meaning the text could not be converted to UTF-8. It is used internally via ensureUtf8Encoded before text is written into documents.

Solutions

  1. Ensure the mbstring extension is installed so mb_convert_encoding is always available.
  2. Pre-sanitize input with mb_check_encoding($value,'UTF-8') and fix the source encoding explicitly (iconv with //IGNORE).
  3. Set correct connection/character-set encoding (e.g. mysql charset utf8mb4) so text arrives as UTF-8 already.
  4. Replace truly invalid bytes before conversion, e.g. iconv('Windows-1252','UTF-8//IGNORE',$value).

Example fix

// before
$textrun->addText($row['name']); // Latin-1 from legacy DB
// after
$name = mb_check_encoding($row['name'], 'UTF-8')
    ? $row['name']
    : iconv('Windows-1252', 'UTF-8//IGNORE', $row['name']);
$textrun->addText($name);
Defensive patterns

Strategy: try-catch

Validate before calling

if (is_string($value) && !mb_check_encoding($value, 'UTF-8')) {
    $value = iconv('Windows-1252', 'UTF-8//IGNORE', $value);
}

Try / catch

try {
    $textrun->addText($value);
} catch (\PhpOffice\PhpWord\Exception\Exception $e) {
    if (str_contains($e->getMessage(), 'UTF-8')) {
        $textrun->addText(mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1//IGNORE'));
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: ensureUtf8Encoded()/toUTF8() called with a non-null string that is not valid UTF-8 and mb_convert_encoding($value,'UTF-8','ISO-8859-1') returns false (e.g. invalid input bytes, or mbstring absent and utf8_encode unavailable/blocked in PHP 8.2+).

Common situations: Text read from legacy databases or CSVs in Latin-1/Windows-1252 with byte sequences mbstring rejects; PHP 8.2+ where utf8_encode is deprecated and mbstring is not installed; passing null-adjacent or binary data as text.

Related errors


AI-assisted analysis of PHPOffice/PHPWord@aef95c0415 (2026-09-14). Data as JSON: /api/errors/55c4929f9987153a. Report an issue: GitHub.

Appendix: source

Thrown at src/PhpWord/Shared/Text.php:157

    public static function isUTF8($value = '')
    {
        return is_string($value) && ($value === '' || preg_match('/^./su', $value) == 1);
    }

    /**
     * Return UTF8 encoded value.
     *
     * @param null|string $value
     *
     * @return ?string
     */
    public static function toUTF8($value = '')
    {
        if (null !== $value && !self::isUTF8($value)) {
            // PHP8.2 : utf8_encode is deprecated, but mb_convert_encoding always usable
            $value = (function_exists('mb_convert_encoding')) ? mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1') : utf8_encode($value);
            if ($value === false) {
                throw new Exception('Unable to convert text to UTF-8');
            }
        }

        return $value;
    }

    /**
     * Returns unicode from UTF8 text.
     *
     * The function is splitted to reduce cyclomatic complexity
     *
     * @param string $text UTF8 text
     *
     * @return string Unicode text
     *
     * @since 0.11.0
     */
    public static function toUnicode($text)

View on GitHub (pinned to aef95c0415)