I am trying to enable private files via features, in code, or with drush but am getting errors.

With drush:

drush vset file_private_path sites/default/files/private

In code:


The problem is that when you set this configuration manually, the file system settings form gets saved and it creates an .htaccess file in that location. When you set it in code, it doesn't create the .htaccess file until you visit the admin/config/media/file-system page, which it returns an error the first time:

Warning: file_put_contents(private:///.htaccess) [function.file-put-contents]: failed to open stream: "DrupalPrivateStreamWrapper::stream_open" call failed in file_create_htaccess() (line 502 of /sandbox/d7/includes/file.inc).

Is there a correct way to be doing this programmatically? Thanks in advance.

  • Good question. I have the same problem. Did you ever find a good solution to this?
    – JW.
    Commented Sep 15, 2015 at 2:02

2 Answers 2


I would not re-create what the form does by hand as @Ayesh does. There is a small chance this form will do more things in a future minor drupal release date (maybe that should never happen, i'm not 100% sure).

What you want to do is look at drupal_form_submit() to programmatically submit a form -- its like visiting the form in a webpage and submitting it without ever opening a browser window. Whatever logic that form does upon submission -- will still happen, eg. create an .htaccess file for you.

You would put the following code into your module install() hook, or you could drush ev this code or make a small php script and run drush php-script myscript.php


$form_state = array();
$form_state['values']['file_private_path'] = 'sites/default/files/private';
$form_state['values']['op'] = t('Save configuration');
drupal_form_submit('system_file_system_settings', $form_state);

You can then re-submit the form and set the default file serve mode from public to private. Or I would use drush vset or just variable_set somewhere in PHP to set the default file serving mode in drpual. My point is that this is the correct way to programmatically submit a form.

  • Your solution does work (no errors when I view the File System page), but I get a few errors when the code is run from my feature's install() hook: gist.github.com/ed21b306d6f45ba5ecb3
    – Vincent
    Commented Oct 4, 2012 at 13:01
  • Looks like a configuration issue. Are you trying to make all of default private? I dont see a folder in your private path in the error message. Drupal is complaining it cant write a file to that directory -- thats a permissions issue (or an unreachable/invalid directory).
    – tenken
    Commented Oct 4, 2012 at 20:14
  • I'm not trying to make it the default, I'm just trying to set the path and create the directory and its .htaccess file. We want to make the option available to different sites out of the box on our large-scale installation without them having to know to enter sites/default/files/private. It did in fact create the directory and .htaccess file without a problem.
    – Vincent
    Commented Oct 4, 2012 at 20:23
  • How did you derive the values to send to drupal_form_submit()?
    – Vincent
    Commented Oct 8, 2012 at 20:33
  • I use firebug. See this howto blogpost: lionide.wordpress.com/2010/12/06/…
    – tenken
    Commented Oct 9, 2012 at 19:30

variable_set() simple saves the value to the database and clear internal cache. Nothing else.

So, before setting the value, you must verify that path is writable and prepare it (.htaccess stuff).

$path = 'sites/default/files/private';
if (is_dir($path) && is_writable($path)){
  file_create_htaccess($path); // for private dir. Use file_create_htaccess($path , FALSE); for public dir.


you can also drupal_mkdir() and drupal_chmod() $path if you want to make sure it's writable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.