phalcon/cphalcon · error · Phalcon\Storage\Serializer\Exceptions\InvalidUnserializationInput
Data for the unserializer must be of type string
Error message
Data for the unserializer must be of type string
What it means
Base64::unserialize(mixed data) requires the raw stored payload to be a string; any non-string input (int, float, bool, null, array, or the false a failed read returns) throws InvalidUnserializationInput before decoding starts. It is the decode-side twin of error 716.
Source
Thrown at phalcon/Storage/Serializer/Base64.zep:41
*/
public function serialize() -> string
{
if typeof this->data !== "string" {
throw new InvalidSerializationInput();
}
return this->phpBase64Encode(this->data);
}
/**
* Unserializes data
*/
public function unserialize(mixed data) -> void
{
var result;
if typeof data !== "string" {
throw new InvalidUnserializationInput();
}
let result = this->phpBase64Decode(data, true);
if unlikely false === result {
let this->isSuccess = false,
result = "";
} else {
let this->isSuccess = true;
}
let this->data = result;
}
}
View on GitHub (pinned to b7419de9cd)
Solutions
- Guard the payload: if (!is_string($raw)) { /* treat as miss */ } before unserialize()
- Make all writers to a shared backend use the same serializer and version
- json_encode()/base64_encode() at the boundary so every stored value is a string
- Clear stale entries when the serializer configuration changes (flush or version the prefix)
Example fix
// before $serializer->unserialize($raw); // $raw = 42 from a foreign writer -> throws // after $serializer->unserialize(is_string($raw) ? $raw : ''); // or treat non-strings as a cache miss
Defensive patterns
Strategy: type-guard
Validate before calling
if (!is_string($raw)) {
return $default; // treat non-string payloads as a cache miss
}
$serializer->unserialize($raw); Type guard
function isBase64Payload(mixed $raw): bool
{
return is_string($raw) && $raw !== '';
} Try / catch
try {
$serializer->unserialize($raw);
} catch (\Phalcon\Storage\Serializer\Exceptions\InvalidUnserializationInput $e) {
// foreign or corrupted entry — drop it and continue as a miss
$cache->delete($key);
return $default;
} Prevention
- Keep serializer settings identical across every writer of a shared backend
- Flush or version the cache prefix when changing serializers
- Treat raw backend bytes as untrusted: type-check before decoding
When it happens
Trigger: Storage backend returns a non-string raw value — another writer on the shared Redis/Memcached stored an unserialized scalar with SERIALIZER_NONE; manually calling unserialize() on data from cookies or external sources that is not actually base64 text; passing the result of a failed get() (false) back into the serializer.
Common situations: Shared cache between apps with different serializer settings; cache entries written by an older config or a different serializer; custom code paths that feed already-decoded values into unserialize().
Related errors
- Data for the serializer must be of type string
- Data for the unserializer must be of type string
- Invalid WHERE clause conditions
- Invalid bind parameter (1)
- Cannot set Memcached client options
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/15e10feb02a34fca.
Report an issue: GitHub.