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
- Ensure the mbstring extension is installed so mb_convert_encoding is always available.
- Pre-sanitize input with mb_check_encoding($value,'UTF-8') and fix the source encoding explicitly (iconv with //IGNORE).
- Set correct connection/character-set encoding (e.g. mysql charset utf8mb4) so text arrives as UTF-8 already.
- 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
- Install ext-mbstring everywhere (it is effectively required on PHP 8.2+)
- Set correct DB connection charset (utf8mb4) so text arrives as UTF-8
- Sanitize third-party/legacy text with mb_check_encoding before adding to documents
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
- Failed to convert password to UCS-2LE
- Invalid value, on of ' . implode(', ', $position) . '…
- Invalid value, on of ' . implode(', ', $restartNumbers) . '…
- Invalid value, dirty or clean possible
- Invalid value, alignments of ' . implode(', '…
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)