I have problems establishing a private files directory (D7.22)

I started at reading this article: http://drupal.org/documentation/modules/file. I then created a private folder above the Drupal root, and entered its path ../private at admin/config/media/file-system. Despite being warned about the performance implications, I chose the Default download method as Private local files served by Drupal. Then, in a content type I created a native file field named Attachment, with Upload destination set to Private files. Widget: File.

At this stage I imagined that these settings would cause an uploaded file to go inside the ../private directory. Nope, instead they go into public directory sites/default/files. Was my assumption wrong?

I tried the following debugging changes - but to no avail:

  • changed ../private to sites/default/files/secure
  • changed field widget to Media file selector
  • changed default download method to Public local files served by Drupal

Is it a site ghost? Am I doing anything wrong? I really see no reason for this not to work. I'm close to filing a bug issue but would appreciate someone confirm that on their installation before I do so.

  • In my experience all you have to do is set the directory and make sure it is writable (I have used sites/default/files/private). Sounds like something strange going on.
    – rooby
    Apr 21, 2013 at 12:43

2 Answers 2


I'm using private upload on several sites and can confirm that this works. So no need to file a bug issue.

At this stage I imagined that these settings would cause an uploaded file to go inside the ../private directory. Nope, instead they go into public directory sites/default/files. Was my assumption wrong?

No. This is indeed what should have happened.

So just to make sure, I set up a site to your exact specifications. I.e. with Drupal root in /demo/drupal and the private directory in /demo/private (where / is the Unix file system root).

I first tested it using the absolute path (i.e. /demo/private as the private upload directory). That worked without a glitch.

I then re-tested it using the relative path to the same directory (i.e. ../private). That also worked without a glitch.

I also noted that Drupal threw the following error if I tried to input a non-existing directory as the private upload directory:

Warning: mkdir(): Permission denied in drupal_mkdir()
 (line 2341 of /demo/drupal/includes/file.inc).
 The directory /demo/bogus does not exist and could not be created.

In other words: If Drupal allow you to use ../private as the private upload directory without throwing this error, your setup should work for private upload.

Drupal will automatically place a .htaccess-file in the private upload directory to protect it against prying eyes. However, for best security, the private upload directory should be above the web-root.

PS: As for the file being "served merrily to an anonymous user", this will happen if the anonymous user is granted access to the node the privatly uploaded file it attached to.

All that the "private download method" does, is to extend Drupal's access control system so that files attached to nodes are made inaccesible to those who happen to know their URL. It does so by pretending that the attachement is stored in the fictitious directory (system/files/). Since this directory does not exist, bypassing Drupal by converting the path into an URL and requesting it directly from the web server will not work.

This is different from, and more secure than the "public download method". This method let those who know a file attachement URL bypass Drupal's access control.

  • Thanks Gisle, I hoped for your hint to work, but unfortunately - changing to/demo/private did not help. Changing the attributes from 755 (just as public files) to 777 did not help either. Apr 21, 2013 at 12:59
  • demo is at root on my hosting. My installation is at demo/drupal. My private directory is as demo/private. Apr 21, 2013 at 13:40
  • Thanks Gisle, in fact you helped a lot by confirming the setup. I set up a blank site too and the private folder was established successfully. However it behaved with one major glitch: the link to a private file, eg. system/files/filename.jpg was served merrily to an anonymous user (another browser). This is a no-no for production. And as I can't afford fighting this issue anymore at this time, I have written a small module which provides its own download callback using raw php code. Thanks so much again! Apr 21, 2013 at 16:42
  • I guess moderator will soon ban us from further discussing the issue here. I will gladly grant you access to my site if you PM me, so that you will be able to see for yourself. :) Apr 21, 2013 at 16:50

Thanks a million. Simply putting the private folder under the sites/default/files folder did it for me, because really the private system of drupal put in an .htaccess file, that confuses anyone who tried to directly download the file using the url. So for clarity, set up the private folder in media configuration to be : sites/default/files/private Greg

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.