Do you have a problem with some Drupal admin pages with a large number of input fields not saving? Does the page just returns back with no message confirming that changes have been saved?

Well, this happened recently on a site that we were troubleshooting for a client.

The symptoms were: trying to save has lots of input fields, a) comes back with no message about saving changes, and b) the values changed were not saved.

The site had 210 enabled modules, 14 user roles defined, and 84 content types, with 76 content fields!

For example, take the permissions page at admin/users/permissions. If the site has lots of content types, each with lots of fields, then modules with many permutations of permissions for content types and fields will each have to define reams and reams of permissions each.

For this site, it was the following modules, combined with the number of content types and fields that caused the permissions to grow like that.

  • node
  • actions_permissions
  • publishcontent
  • content_permissions

Let us verify that by saving the permissions page as HTML, and then doing some analysis:

$ grep -c 'input type="checkbox"' permissions.html 
20748

Look at that: 20,748 checkboxes!

Let us see how many permissions we have:

$ grep -c 'class="permission"' permissions.html        
1482

Yup! That is 1,482 permissions!

If you multiply 1482 X 14 roles = 20,748 total checkboxes!

The root cause for this was two fold, one on the PHP side and the other on Apache's side.

Configuring PHP to accept more input variables

The default value for input fields for PHP is 1000. While this is sufficient for normal sites, it is not so for sites that overuse (misuse/abuse?) Drupal features.

You need to increase the number of input variables in PHP:

To verify that this is your problem, look in your web server's error log for something similar to this error message:

mod_fcgid: stderr: PHP Warning: Unknown: Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini. in Unknown on line 0

Just add the following to your php.ini file:

max_input_vars = 1500

If you have the Suhosin enhanced security extension for PHP, then you need to add these as well:

suhosin.post.max_vars = 1500
suhosin.request.max_vars = 1500

Then, restart your web server.

You should be able to save the page now, and get a confirmation message, and see that your changes have "stuck".

But wait a minute: how come you have over 20,000 checkboxes, yet you only made it work with 1500 only?

The answer is that Drupal is using input value arrays for most fields, so it is not a 1 to 1 relationship between number of checkboxes and number of input fields.

Configuring FastCGI for large input

If you are using FastCGI, for example mod_fastcgi or fcgid, then pages would not save even if you implement the above changes. The reason is that with that many input fields, you overflow the default maximum for the size of requests between Apache (or ngnix) and PHP over the FastCGI protocol.

Look in your server's error log for an error message like this one:

mod_fcgid: HTTP request length 131998 (so far) exceeds MaxRequestLen (131072)

Normally, either you will see the errors in the web server's error log, or you will see them right there on the page. But we have had cases where low cost web hosts don't log errors at all anywhere.

The default is 128 Kilobytes (128 X 1024 = 131,072 bytes), and was not enough for this huge number of fields.

To confirm that you are running FastCGI, go to /admin/reports/status/php. If "Server API" is set to "CGI/FastCGI", then continue with the next step.

The fix is easy, and would go under either FastCGI or fcgid, as the case may be with your setup:

For example if you are using fcgid, you would add that under the IfModule mod_fcgid.c section:

  FcgidMaxRequestLen  524288

If you are using the older FastCGI, then you need to add that under the IfModule mod_fastcgi.c section.

Once the above was changed, we got the page to display the reassuring message of "The changes have been saved" appearing, and combined with the max_input_vars change above, the values were saved correctly.

Comments

Mon, 2012/10/22 - 17:48

Very interesting post!

Since I would have run into this problem someday as well, a big thank you!

Wed, 2012/10/24 - 13:58

I've had this issue at admin/build/blocks as well. In that case you get absolutely no warning on-screen, but the last N number of blocks that were assigned to a region are now unassigned.

Wed, 2012/10/24 - 14:25

Yeah, that client had this issue too, but we solved it via the permissions fix.

It happens because of truncation. Whatever the buffer size for the request (FastCGI), or the number of input variables, anything above that is silently ignored.

Fun!

Thu, 2012/10/25 - 18:18

Funny that you can work with Drupal for years and then a problem will present for the first time. This happened to us the day before I read this post.

Thu, 2012/10/25 - 19:30

Hello Sime ...

We do see a lot of stuff while we help clients. Maybe we see too many extreme cases, because they are the ones seeking help with performance or scalability ...

Fun to share what we find ...

Is your Drupal or Backdrop CMS site slow?
Is it suffering from server resources shortages?
Is it experiencing outages?
Contact us for Drupal or Backdrop CMS Performance Optimization and Tuning Consulting