Last updated January 17, 2012. Created by johnbarclay on July 24, 2009.
Edited by debrajn, xtfer, larowlan, tobiasb. Log in to edit this page.
Improperly Serialized Variables in Database
When loading a page the following error occurs when loading an improperly serialized array from the variables table. The same technique can be used for bad serialized data in other tables.
Error
PHP Notice: unserialize() [<a href='function.unserialize'>function.unserialize</a>]: Error at offset 6 of 10 bytes in \includes\bootstrap.inc on line 428
Depending on how caching is set on your site, you may only see this error sometimes. Because once the variables are cached they may not be loaded every time.
Some Causes of Serialization Issues
- Changing serialized content via sql replace command such as when migrating a site. You can't do this unless you follow up and put the
length of the new value in by hand. - Serializing resources
- Serializing objects and unserializing them without the class code loaded
- Serialized string is truncated because it is too long for the field it is stored in.
- Encoding/Decoding PHP/mysql issues
- Incorrect installation/compilation/configuration of APC (php extension)
Debugging Technique
Around line 550 of bootstrap.inc in drupal 6 change the code to as follows. (Set aside the old code to replace afterward) This will show you the variables that are throwing errrors. The @ symbol before unserialize suppresses the error so all the variables can be checked before code execution stops.
// if ($cached = cache_get('variables', 'cache')) {
// $variables = $cached->data;
// }
// else {
$result = db_query('SELECT * FROM {variable}');
while ($variable = db_fetch_object($result)) {
$variables[$variable->name] = @unserialize($variable->value);
if ($variables[$variable->name] === FALSE) {
print "<hr/>Unserialize Error for variable:". $variable->name . '='. $variables[$variable->name] . "<br/>". $variable->value;
}
}
die;
cache_set('variables', $variables);
// }
You may only get the error when variables are first loaded. After that they may be cached. So to reproduce the error, flush the cache via sql:
truncate table cache_block;
truncate table cache;
truncate table cache_content;
truncate table cache_filter;
truncate table cache_form;
truncate table cache_menu;
truncate table cache_views;Resolution
If you are getting errors with all or many of your variables, this technique will not work as the cause is likely not isolated bad record(s) in your variables table.
Once you find the bad variable(s), you will need to fix it in the database. (You may also override the variable by setting its value in the $conf array as described at the bottom of the settings.php file but you will not be able to change the variable value via the web interface until you remove the override in settings.php)
Below are what serialized arrays should look like. (look in the variables table):
name: node_options_bio
value: a:1:{i:0;s:6:"status";}
name: googleanalytics_track_6
value: b:0;The i represent integers, s strings, and the count is the length within the quotes.
You may be able to fix the value by hand editing it the database table. If you can't, you may just want to delete it, saving the old value somewhere, and let Drupal set it to its default. This may cause problems for some variables.
How you can remove the above error.
// Added by Deb
-- Open includes/bootstrap.inc file drupal 6.22
-- Go to line no 568
-- Paste below code after the line no 568 or "$variables[$variable->name] = unserialize($variable->value);" line.
if ($variables[$variable->name] === FALSE) {
variable_set($variable->name, ""); //here all the blank variable will be true
}
-- After changing all the necessary variable in database (variable table), please delete the edited code and clear the cache and truncate the watchdog table and refresh the page again.
--Check in admin "recent log entries"APC related issues
Incorrect installation, configuration or compiling of the php extension APC from the PECL repository can also produce similar unserialize errors. If you have the APC extension enabled, try disabling it in your php.ini (look for extension=apc.so) and then restarting your web-server.
If disabling APC fixes the issue then it is likely that it has not been installed correctly or that the extension is incorrectly configured. Please consult the php manual for the correct way to install the extension for your particular server.
Red-hat based servers (Fedora, RHEL, Centos) can use yum to install the package php-pecl-apc instead of using pecl install apc. Using yum to install the extension instead of building it with PECL seems to fix the unserialize issues in some instances on these distributions.
Comments
A different approach
To find which variables are not serialized correctly, I created a block with this code, using the PHP input format:
<?php
$result = db_query('SELECT * FROM {variable}');
while ($variable = db_fetch_object($result)) {
$variables[$variable->name] = @unserialize($variable->value);
if ($variables[$variable->name] === FALSE) {
print "<hr/>Unserialize Error for variable:". $variable->name . '='. $variables[$variable->name] . "<br/>". $variable->value;
}
}
?>
It's much more practical (and safe) than messing up with Drupal core files.
Booleans
If, which is very likely, you've got variables storing just a serialized version of the boolean FALSE ("b:0;"), the above code will consider it an error.
I suggest modifying it slightly to ignore that case:
<?php$serialized_false = serialize(FALSE);
$result = db_query('SELECT * FROM {variable}');
while ($variable = db_fetch_object($result)) {
$variables[$variable->name] = @unserialize($variable->value);
if ($variables[$variable->name] === FALSE && $variable->value !== $serialized_false) {
print "<hr/>Unserialize Error for variable:". $variable->name . '='. $variables[$variable->name] . "<br/>". $variable->value;
}
}
?>
I don't like the above
I don't like the above methods of debugging because you don't want to suppress the unserialize error output.
I like to use this bit of PHP:
#!/usr/bin/php
<?php
$conn = new MySQLi('localhost', 'root', '', 'drupal_gypsy');
if (!$conn) {
die("MySQL error: #{$conn->connect_errno}: {$conn->connect_error}");
}
$result = $conn->query("select * from gypsy_variable");
while ($row = $result->fetch_row()) {
print $row[0];
$data = unserialize($row[1]);
print " ";
print $data . "\n";
print "-------------------\n";
}
It shows I have one corrupted row whose data is this:
a:27:{s:17:"zen_block_editing";i:0;s:14:"zen_breadcrumb";s:2:"no";s:24:"zen_breadcrumb_separator";s:5:" › ";s:19:"zen_breadcrumb_home";i:1;s:23:"zen_breadcrumb_trailing";i:1;s:20:"zen_breadcrumb_title";i:0;s:20:"zen_rebuild_registry";i:0;s:14:"zen_wireframes";i:0;s:11:"toggle_logo";i:1;s:11:"toggle_name";i:1;s:13:"toggle_slogan";i:0;s:14:"toggle_mission";i:0;s:24:"toggle_node_user_picture";i:0;s:27:"toggle_comment_user_picture";i:0;s:13:"toggle_search";i:0;s:14:"toggle_favicon";i:1;s:20:"toggle_primary_links";i:1;s:22:"toggle_secondary_links";i:0;s:12:"default_logo";i:0;s:9:"logo_path";s:43:"sites/gypsyfalls/files/hg_template_logo.png";s:11:"logo_upload";s:0:"";s:15:"default_favicon";i:0;s:12:"favicon_path";s:41:"sites/gypsyfalls/themes/gypsy/favicon.ico";s:14:"favicon_upload";s:0:"";s:14:"default_banner";i:0;s:11:"banner_path";s:0:"";s:13:"banner_upload";s:0:"";}Good lord! Where's the problem? Well, the error from unserialize says:
Notice: unserialize(): Error at offset 108 of 876 bytes in /data/www/gypsyfalls/find_bad_var.php on line 14
Using this and "cut" under Linux, I can at least get the context:
$ cut --bytes=104-112 bs2› ";s:
Text search for that and I see it's this guy:
s:5:" › "That's an s:3 not an s:5!!
VERY DISTURBING that there's a PHP or Drupal bug that's corrupting my variables table! Anybody know of an existing ticket somewhere I can pile onto?
See module variablecheck
http://drupal.org/node/1017082#comment-4286694
http://2tell.org/boring
Good Debugging Technique
Thanks Johnbarclay, xtfer, larowlan and tobiasb
This code is very much helpful for me. I have added extra piece of info please see section
How you can remove the above error
Regards,
Deb
Do not alter values manually
Do not alter values manually
You can use Online Sterilizer here
Thanks.
Nikhil Mohan