laravel/framework · error · RuntimeException
Strings with invalid UTF-8 byte sequences cannot be escaped.
Error message
Strings with invalid UTF-8 byte sequences cannot be escaped.
What it means
Thrown by Connection::escape() when preg_match('//u', $value) fails, i.e. the string is not valid UTF-8. The driver-level quote()/escapeString assumes a valid encoding, so the framework bails rather than emit a malformed literal that could be misinterpreted by the server.
Source
Thrown at src/Illuminate/Database/Connection.php:1186
public function escape($value, $binary = false)
{
if ($value === null) {
return 'null';
} elseif ($binary) {
return $this->escapeBinary($value);
} elseif (is_int($value) || is_float($value)) {
return (string) $value;
} elseif (is_bool($value)) {
return $this->escapeBool($value);
} elseif (is_array($value)) {
throw new RuntimeException('The database connection does not support escaping arrays.');
} else {
if (str_contains($value, "\00")) {
throw new RuntimeException('Strings with null bytes cannot be escaped. Use the binary escape option.');
}
if (preg_match('//u', $value) === false) {
throw new RuntimeException('Strings with invalid UTF-8 byte sequences cannot be escaped.');
}
return $this->escapeString($value);
}
}
/**
* Escape a string value for safe SQL embedding.
*
* @param string $value
* @return string
*/
protected function escapeString($value)
{
return $this->getReadPdo()->quote($value);
}
/**View on GitHub (pinned to bd6b5437e6)
Solutions
- Fix the source encoding: convert before escaping with mb_convert_encoding($value, 'UTF-8', 'UTF-8') to drop invalid bytes, or from the real source encoding.
- If the data is genuinely binary, use $connection->escape($value, binary: true).
- Validate and sanitize input with iconv('UTF-8', 'UTF-8//IGNORE', $value) before escaping.
- Bind the value as a parameter instead of escaping it inline, when the driver accepts the raw bytes.
Example fix
// before $sql = '... where name = '.$conn->escape($dirtyLatin1); // after $clean = mb_convert_encoding($dirtyLatin1, 'UTF-8', 'UTF-8'); $sql = '... where name = '.$conn->escape($clean);
Defensive patterns
Strategy: validation
Validate before calling
if (is_string($value) && preg_match('//u', $value) === false) {
$value = mb_convert_encoding($value, 'UTF-8', 'UTF-8');
// or, if truly binary: $connection->escape($value, binary: true)
}
$literal = $connection->escape($value); Type guard
function isValidUtf8(string $v): bool {
return preg_match('//u', $v) === 1;
} Prevention
- Normalize inbound strings to UTF-8 at the boundary (mb_convert_encoding).
- Detect and reject/clean invalid byte sequences before escaping.
- Treat non-UTF-8 payloads as binary if they are genuinely binary.
- Bind values as parameters when the driver accepts the raw bytes.
When it happens
Trigger: Calling $connection->escape($string) on a string with invalid UTF-8 byte sequences (truncated multibyte char, legacy Latin-1 / ISO-8859-1 text, binary garbage masquerading as text).
Common situations: Importing legacy non-UTF-8 data; scraping HTML declared as a different encoding; reading a partial multibyte sequence from a stream; concatenating raw bytes from an external API.
Related errors
- The database connection does not support escaping arrays.
- The given password does not match the current password.
- You requested {$requested} items, but there are only {$count
- $count items were found.
- Step value must be at least 1.
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/0b4243f0bbaa065a.json.
Report an issue: GitHub.