Solving "Malformed UTF-8 characters, possibly incorrectly encoded" error in Laravel

Here is a short blog for a problem I ran into this evening. I was testing a new endpoint that returns some user data in JSON format. Once every while the test was failing, it was flaky.

The error

The error was this one:
Malformed UTF-8 characters, possibly incorrectly encoded at /path/to/vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php:75.

The cause

Since the problem only happened once every couple of tests (and helped by the error message itself) I figured it must be related to the random user that I test with.

This turned out to be true. When a name contains some accented character, like "Ç", this error occured.

The solution

The solution turned out to be in my application code, it has nothing to do with Laravel itself.

The initials of the user are part of the return data. So in case of a user named "Isabella Özkan", those would be "IÖ".

The old code for getting the initials was using strtoupper and substr like this:

public function initials(): string
    return strtoupper(substr($this->first_name, 0, 1) . substr($this->last_name, 0, 1));

But these functions are not multi-byte safe and so they can give incorrect results for multi-byte characters. To solve this we should use the equivalent multi-byte safe functions:

public function initials(): string
    return mb_strtoupper(mb_substr($this->first_name, 0, 1) . mb_substr($this->last_name, 0, 1));

That should do it. By using the correct string functions you make sure all characters are properly handled. This, in turn, will allow everything to be outputted as a JSON response without problems.

Happy coding!

Read some more

Comments (3)

Got a question? Liked the article or got a suggestion? Leave a comment to let us know.

Thanks for the contribution. I was able to solve a similar problem after 4 hours :D
MANY thanks for this. i think I got lucky when searching as a few Stack overflow threads indicated people have lost hours on this issue. Thankfully this page came up and resolved my issue immediately. Cheers!
I feel really lucky to have read this blog. My discovery of the source of the problem occurred the moment I saw the strtoupper function. Probably saved me a few hours.