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) === false, i.e. the string is not valid UTF-8. The framework escapes string literals assuming UTF-8 (the default client encoding for the supported drivers); non-UTF-8 bytes cannot be safely embedded and would corrupt the literal, so it rejects them.
Solutions
- If the bytes are genuinely binary, escape with $binary=true: $connection->escape($value, true).
- Re-encode the string to UTF-8 before escaping: mb_convert_encoding($value, 'UTF-8', 'UTF-8') (or from the source encoding).
- Validate/repair encoding up front (mb_check_encoding) and drop or replace invalid sequences.
- Bind the value as a parameter so PDO handles encoding rather than escaping it inline.
Example fix
// before $conn->escape($latin1String); // after $conn->escape(mb_convert_encoding($latin1String, 'UTF-8', 'Windows-1252'));
Defensive patterns
Strategy: validation
Validate before calling
if (is_string($value) && mb_check_encoding($value, 'UTF-8') === false) {
$value = mb_convert_encoding($value, 'UTF-8', 'UTF-8'); // drop invalid seqs
}
$escaped = $connection->escape($value); Type guard
function isValidUtf8(string $value): bool {
return mb_check_encoding($value, 'UTF-8');
} Try / catch
try {
$sql = $connection->escape($value);
} catch (\RuntimeException $e) {
if (str_contains($e->getMessage(), 'UTF-8')) {
$sql = $connection->escape($value, true); // treat as binary
} else { throw $e; }
} Prevention
- Validate input encoding at trust boundaries with mb_check_encoding().
- Re-encode legacy data to UTF-8 before passing it to escape().
- For genuine binary payloads, use the $binary=true flag.
When it happens
Trigger: Calling $connection->escape($s) where $s is a non-UTF-8 string (latin1/Windows-1252/raw bytes); concatenating output from a non-UTF-8 source (legacy API, gzip decode of binary, iconv without //IGNORE); binary data misrouted to the string branch.
Common situations: Importing legacy data with latin1 encoding; consuming an external feed that lies about charset; binary payloads that should have used the $binary flag.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Strings with null bytes cannot be escaped. Use the binary…
- The database connection does not support escaping arrays.
- The database connection does not support escaping binary…
- A driver must be specified.
- Cannot establish connection [$name] because another…
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/0b4243f0bbaa065a.
Report an issue: GitHub.
Appendix: 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 e0f6eb3518)