“No input file specified” is one of the most frequently encountered issues in Nginx. People on serverfault and in the #nginx IRC channel asks for help with this so often that this post is mostly to allow me to be lazy and not have to type up the same answer every time.
This is actually an error from PHP and due to display_errors being 0 people will often just get a blank page with no output. In a typical setup PHP will then send the error to stderr or stdout and Nginx will pick up on it and log it in the Nginx error log file. Thus people spend a ton of time trying to figure out why Nginx isn’t working.
The root cause of the error is that PHP cannot find the file Nginx is telling it to look for, and there are two common cases that causes this. Either you’re not giving PHP the right path to the file or your file permissions are incorrect.
Wrong Path Sent to PHP
The most common reason at the time of writing happens because a user uses a horrible tutorial found via google instead of actually understanding Nginx. Reading my primer will equip you to actually solve this on your own but since this post is actually dedicated to the error I’ll cheat this once and allow you to be lazy by just giving you the full solution.
Nginx tells PHP about the file to execute via the SCRIPT_FILENAME fastcgi_param value. Most examples in the wiki should define this as $document_root$fastcgi_script_name. The horrible tutorials will often hardcode the path value but this is not desirable as we don’t want to duplicate information and invite future screw ups. So you’ve gone with the $document_root$fastcgi_script_name option and suddenly it’s no longer working.
This happens because Nginx has 3 levels of inheritance commonly referred to as blocks, these being http, server and location, each being a sub-block of the parent. Directives in nginx inherit downwards but never up or across, so if you define something in one location block it will never be applied in any other location block under any circumstance.
Typically users define their index and root directive in location / because a tutorial told them to. So when they then define SCRIPT_FILENAME using $document_root the root directive is not actually defined and thus the SCRIPT_FILENAME value becomes just the URI making PHP look at the root server dir.
The simple solution here is to just define the directive in your server block. (or http block even!) Generally the higher up your can define a directive the less duplicate directives you’ll need.
Incorrect File Permissions
Most people don’t really believe me when I tell them their file permissions are incorrect. They’re looking at the damn permissions and the PHP user can read the file just fine! Sadly, this shows a lack of understanding of Unix user permissions. Being able to read a file is not enough, a user must also be able to traverse to the file.
This effectively means that not only should the file have read permission, but the entire directory structure should have execute permission so that the PHP user can traverse the path. An example of this:
Say you have an index.php file in /var/www. /var/www/index.php must have read permission and both /var and /var/www must have execute permissions!
If you’ve corrected both things and still have this issue then please put a comment so I can look into it, as far as I know there should be no other reasonsĀ for this error.
Related posts:


Twitter
LinkedIn
Hey there!
I think you were it who telled me to read this yesterday in nginx-irc.
What i wan’t to say is in first line thanks, i’m on the way to understand how nginx work.
But there is one thing i really have to ask.
Do you mean the root-directive should be put from location – block to the server – block?
My english isn’t as good in some specific “slangs”, so i don’t really know.
Yeah you want your root directive in your server block as the $document_root variable is then available in all your location blocks. So if you pass to a backend and have to provide a path to the file to execute you can then use the $document_root variable and avoid duplicating your paths.
Thanks! Clearly written about the problem and I solve it.
I wish I’d read your Nginx Primer when I first come to nginx, so I don’t need to waste my time on solving this problem.
Anyway, I’m reading your Nginx Primer now
Hi Martin
Thanks for the explanation.
May I ask you one question though? Why do people use SCRIPT_FILENAME = $document_root$fastcgi_script_name
I’ve installed Nginx from a package, and this is a default FastCGI param:
fastcgi_param SCRIPT_FILENAME $request_filename;
Why would I change it to $document_root$fastcgi_script_name
Many thanks
$request_filename is actually just a shortcut for the document root (or alias) + the request URI. This means that so long as you do not rely on fastcgi_index then you can safely use $request_filename instead of $document_root$fastcgi_script_name.
The important part is still that you keep root defined in server context so that it’s available in your PHP location.
Thanks for that reply Martin.
One more question: do you think there’s a lot of overlap between Nginx, Varnish and the W3 Total Cache WordPress plugin?
For example, does the W3 page cache overlap with the Varnish cache? Intuitively, I imagine Varnish cache is quicker because (in my case – with malloc) it’s using memory. I’d like to reduce overlap so am wondering if the perfect WordPress solution could do without a cache plugin, maybe just a minify plugin.
Then there’s browser caching, Gzip and headers. It seems you can set these from Nginx, Varnish or W3. I imagine a lot of installs out there are duplicating Gzip across Nginx and W3.
I’ve looked through the nginx.conf that W3 produces and it’s quite a mess. To keep things lightweight and simple, I’m thinking about ditching W3. Do you think there’s anything really positive that W3 achieves, other than minify, that’s not possible with Nginx or Varnish?
There’s a lot of overlap between Nginx and Varnish, so much that I don’t even bother with Varnish at all, I just cache with Nginx. Application layer caching that is W3 Total Cache is completely unrelated, though, and I prefer using Memcached for that so it uses memory as well. As for WordPress, it really does need a caching plugin, it’s absolutely horrible without it. W3 with APC or Memcached storage engine is very clean and very easy to use and makes it so much faster.
Thank you for your explanation!I know your means,But i still have some question.I have two work directory,one is D:\NET,one is E:\NET,i use alias or root in the location block,this two location have the same server block,so the server block have one root,when i vister the php files in D:\NET directory,i get a “No input file specified” error at then when i vister php files in E:NET directory,vice versa,In your means,because the root is in D:\NET,not E:\NET,how can i vister the php file at the same time at all of alias or root of location block?
Hi Martin,
I am wondering if there are any other known causes of this error, because I am getting “No input file specified.”, even though the paths and permissions seem fine. I am sorry to reward your excellent blogging by treating you like tech support, but I suspect that if I asked this on a PHP mailing list it might get ignored as an “nginx issue”.
Why do I think my config is fine? The “root” directive is in the server block; in fact if I use tcpdump to evesdrop on the fastcgi traffic, I see ….SCRIPT_NAME/var/www/index.php…”, which looks fine too me. Similarly, the permissions are fine; I can become the same user as the PHP process and “cat” the source file.
So it looks to me like it’s an issue with PHP itself, but I can’t prove it. Frustratingly, I have made all this work without any trouble at all on other machines!
Cheers.
Hi. I just fixed the problem I mentioned abovfe! Mea Culpa I guess, but perhaps this is worth adding to your post: Debian’s version of /etc/nginx/fastcgi_params defines SCRIPT_NAME but not SCRIPT_FILENAME. If I define the latter, things start to work.
Is this a Debian bug? Or is it something else?
It’s not a bug really. fastcgi_params never included SCRIPT_FILENAME from the source, fastcgi.conf does, though. You could kind of consider fastcgi_params as deprecated. If anything it’s a problem of the fastcgi protocol that it defines two variable names which are so close together that people will misread them as being one and the same.
my wordpress website does not seem to work with ur solution.. i have defined the complete root in the location block..
I still get the error “No Input file specified ” for this case
http://lotrix.com/wp-admin
but I dont get the same error for the below case
http://lotrix.com/wp-admin/
- just the forward slash is missing and nothing else.. what do you think might be the problem….
Can’t help you unless you put a link to a pastebin of your config.