Skip to content

Nocache storing serialized regions fails on MySQL due to invalid UTF-8 #14504

@ramononl

Description

@ramononl

Bug description

Since 6.10.0, DatabaseSession::cacheRegion() stores serialize($region) directly into the region column of nocache_regions (#14422). PHP's serialize() produces binary output that is not valid UTF-8 — protected and private object properties are encoded using null byte markers (\x00*\x00, \x00ClassName\x00).

MySQL LONGTEXT columns with utf8mb4 charset correctly reject invalid UTF-8 sequences, resulting in:

SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xDB\xE2\x88\xB2...' for column 'region'`

This can be confirmed by checking the serialized output directly:

mb_check_encoding(serialize($region), 'UTF-8'); // always returns false

A fresh install with minimal content may not trigger this on every request. The failure depends on the specific byte sequence produced at the boundary of null byte property markers and surrounding content. Sites with multibyte content (Arabic, Chinese, Japanese, etc.) or large deeply nested object graphs are most reliably affected, but any site using MySQL + database nocache driver is potentially vulnerable.

Workaround

Wrapping the value in base64_encode/base64_decode produces pure ASCII output that MySQL always accepts, confirming the issue is the binary content of the serialized string:

// write
'region' => base64_encode(serialize($region))

// read
unserialize(base64_decode($region->region), ['allowed_classes' => true])

How to reproduce

All three must be true:

  • nocache driver set to database in config/statamic/static_caching.php
  • MySQL or MariaDB as the database — PostgreSQL and SQLite do not enforce UTF-8 validity on text columns and are unaffected
  • Statamic 6.10.0+ — the serialize() call was introduced in PR [6.x] Serialize nocache regions before storing in cache #14422

Logs

Environment

Local Environment
Laravel Version: 12.56.0
PHP Version: 8.3.30
Composer Version: 2.9.5
Environment: local
Debug Mode: ENABLED
Maintenance Mode: OFF
Timezone: Europe/Zurich
Locale: en

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: NOT CACHED

Drivers
Broadcasting: log
Cache: redis
Database: mysql
Logs: stack / single
Mail: smtp
Queue: sync
Session: file

Storage
public/storage: NOT LINKED

Livewire
Livewire: v4.2.4

Statamic
Addons: 8
Sites: 2 (English, Arabic)
Stache Watcher: Enabled
Static Caching: Disabled
Version: 6.13.0 PRO

Statamic Addons
aerni/livewire-forms: 10.3.1
eminos/statamic-tabs: 2.0.1
jacksleight/statamic-bard-texstyle: 4.1.0
marcorieser/statamic-livewire: 5.3.1
mitydigital/feedamic: 3.0.12
mitydigital/iconamic: 3.0.0
reachweb/statamic-livewire-filters: 4.3.2
statamic/seo-pro: 7.5.0

Installation

Fresh statamic/statamic site via CLI

Additional details

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions