getgrav/grav · error · RuntimeException

Decoding serialized data failed

Error message

Decoding serialized data failed

What it means

Grav's SerializeFormatter::decode() calls PHP's unserialize() (with notices suppressed) and throws this RuntimeException when unserialize() returns false for input that is not literally serialize(false). It means the byte stream handed to the formatter is not valid, complete PHP-serialized data. Typical root causes are truncated or hand-edited files, line-ending/encoding mangling during transfer, or data produced by a different serializer.

Source

Thrown at system/src/Grav/Framework/File/Formatter/SerializeFormatter.php:71

     * {@inheritdoc}
     * @see FileFormatterInterface::encode()
     */
    public function encode($data): string
    {
        return serialize($this->preserveLines($data, ["\n", "\r"], ['\\n', '\\r']));
    }

    /**
     * {@inheritdoc}
     * @see FileFormatterInterface::decode()
     */
    public function decode($data)
    {
        $classes = $this->getOptions()['allowed_classes'] ?? false;
        $decoded = @unserialize($data, ['allowed_classes' => $classes]);

        if ($decoded === false && $data !== serialize(false)) {
            throw new RuntimeException('Decoding serialized data failed');
        }

        return $this->preserveLines($decoded, ['\\n', '\\r'], ["\n", "\r"]);
    }

    /**
     * Preserve new lines, recursive function.
     *
     * @param array $search
     * @param array $replace
     * @return mixed
     */
    protected function preserveLines(mixed $data, array $search, array $replace)
    {
        if (is_string($data)) {
            $data = str_replace($search, $replace, $data);
        } elseif (is_array($data)) {
            foreach ($data as &$value) {

View on GitHub (pinned to 6040efed04)

Solutions

  1. Delete or restore the offending serialized file so Grav regenerates it from defaults (check user/data, user/cache, backup directories).
  2. Verify the file was not modified: compare length/checksum against a backup; re-export rather than hand-edit serialized data.
  3. If the file legitimately contains another format, configure the correct formatter (JsonFormatter/YamlFormatter) for that file instead of SerializeFormatter.
  4. Wrap decode() in a try-catch that treats unreadable data as 'file missing' and rebuilds it.

Example fix

// before
$data = $file->load(); // RuntimeException: Decoding serialized data failed

// after
try {
    $data = $file->load();
} catch (RuntimeException $e) {
    @unlink($file->filename()); // discard corrupt state, rebuild
    $data = $defaults;
    $file->save($data);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Cheap pre-check: valid serialized streams start with a type token
if (!is_string($data) || $data === '' || !preg_match('/^[a-zOCdbsiNa]:\d+/i', $data)) {
    // not serialized data; skip decode or rebuild defaults
}

Try / catch

try {
    $decoded = $formatter->decode($data);
} catch (\Grav\Framework\File\Formatter\Exception\RuntimeException $e) {
    // treat as corrupt: log, restore defaults, and continue
    $decoded = $defaults;
    $log->warning('Corrupt serialized file {file}: {msg}', ['file' => $filename, 'msg' => $e->getMessage()]);
}

Prevention

When it happens

Trigger: Reading a saved .serialized cache/state file that was corrupted, emptied, or truncated; calling $formatter->decode() on a string that was never produced by serialize() (e.g. JSON or plain text); transferring serialized files in a way that converts \n/\r or strips bytes; a file written by an incompatible PHP serialization format.

Common situations: Deploying or copying the grav data/cache directories between servers with FTP in ASCII mode; a cache cleaner or editor truncating files under user/data; switching a file's formatter configuration from JsonFormatter to SerializeFormatter while old files still contain the previous format.

Related errors


AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17). Data as JSON: /api/errors/078fb3b21bca8ec1. Report an issue: GitHub.