Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I recently installed Apache 2.4 on my local machine, together with PHP 5.4.8 using PHP-FPM.

Everything went quite smoothly (after a while...) but there is still a strange error:

I configured Apache for PHP-FPM like this:

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/Users/apfelbox/WebServer"
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://$1

It works, for example if I call http://localhost/info.php I get the correct phpinfo() (it is just a test file).

If I call a directory however, I get a 404 with body File not found. and in the error log:

[Tue Nov 20 21:27:25.191625 2012] [proxy_fcgi:error] [pid 28997] [client ::1:57204] AH01071: Got error 'Primary script unknown\n'


I now tried doing the proxying with mod_rewrite:

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/Users/apfelbox/WebServer"

    RewriteEngine on    
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^/(.*\.php(/.*)?)$ fcgi://$1 [L,P]

But the problem is: it is always redirecting, because on http://localhost/ automatically http://localhost/index.php is requested, because of

DirectoryIndex index.php index.html

Update 2

Ok, so I think "maybe check whether there is a file to give to the proxy first:

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/Users/apfelbox/WebServer"

    RewriteEngine on    
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^/(.*\.php(/.*)?)$ fcgi://$1 [L,P]

Now the complete rewriting does not work anymore...

Update 3

Now I have this solution:

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/Users/apfelbox/WebServer"

    RewriteEngine on    
    RewriteCond /Users/apfelbox/WebServer/%{REQUEST_FILENAME} -f
    RewriteRule ^/(.*\.php(/.*)?)$ fcgi://$1 [L,P]

First check, that there is a file to pass to PHP-FPM (with the full and absolute path) and then do the rewriting.

This does not work when using URL rewriting inside a subdirectory, also it fails for URLs like http://localhost/index.php/test/ So back to square one.

Any ideas?

share|improve this question

After hours of searching and reading Apache documentation I've come up with a solution that allows to use the pool, and also allow the Rewrite directive in .htaccess to work even when the url contains .php files.

<VirtualHost ...>


 # This is to forward all PHP to php-fpm.
 <FilesMatch \.php$>
   SetHandler "proxy:unix:/path/to/socket.sock|fcgi://unique-domain-name-string/"

 # Set some proxy properties (the string "unique-domain-name-string" should match
 # the one set in the FilesMatch directive.
 <Proxy fcgi://unique-domain-name-string>
   ProxySet connectiontimeout=5 timeout=240

 # If the php file doesn't exist, disable the proxy handler.
 # This will allow .htaccess rewrite rules to work and 
 # the client will see the default 404 page of Apache
 RewriteCond %{REQUEST_FILENAME} \.php$
 RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} !-f
 RewriteRule (.*) - [H=text/html]


As per Apache documentation, the SetHandler proxy parameter requires Apache HTTP Server 2.4.10.

I hope that this solution will help you too.

share|improve this answer
This is definitely the answer for 2015, everything else here is crap for a modern setup (Let's say debian stable) – Dmitri DB Jul 4 '15 at 9:50
Second @DmitriDB comment. This is what you want to use for a modern setup using Apache 2.4.10 or greater (this is when unix sockets became supported) – Brady Oct 16 '15 at 11:03
I've been banging my head against the wall on this same problem for quite some time, and I have an extremely similar setup as yours. Would you please post your .htaccess Rewrite directives? From what I understand, everything in this answer is only what you have in your httpd.d/site.conf file. – David W Nov 5 '15 at 10:56
Francesco: Is it possible to make the RewriteRule work for Alias'd URLs? – Zulakis Feb 16 at 9:58
At the moment using this RewriteRule seems quite dangerous as it could expose config.php files in plain if they were inside Aliased directories and therefore not existing in %{DOCUMENT_ROOT}/%{REQUEST_URI}. – Zulakis Feb 16 at 10:12

I ran into this problem yesterday as well – Apache 2.4 moved out of Debian/experimental into Debian/unstable forcing me to deal with this new stuff; not on our production servers of course ;).

After reading what feels like millions of sites, Apache docs, bug reports and debugging output in the error log I finally got it to work. No, there's no support for FPM with sockets, yet. The default Debian config has been using sockets for some time now, so Debian users will have to change that too.

Here's what works for a CakePHP site and PHPMyAdmin (the latter needs some config if you're using the Debian packages though), so I can confirm that mod_rewrite still works as expected to do fancy URL rewriting.

Notice DirectoryIndex index.php, which might be the reason none of your configs worked for "folders" (at least that's what didn't work here).

I still get File not found. for directories, but only if there's no index file it can parse. Would love to get rid of that too, but it's not that critical as for now.

<VirtualHost *:80>
    ServerName site.localhost

    DocumentRoot /your/site/webroot
    <Directory />
            Options FollowSymlinks
            DirectoryIndex index.php
            AllowOverride All
            Require all granted

    <LocationMatch "^(.*\.php)$">
            ProxyPass fcgi://

    LogLevel debug
    ErrorLog /your/site/logs/error.log
    CustomLog /your/site/logs/access.log combined

The above vhost works perfectly well with an .htaccess in the root like this:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]

I don't quite get what you mean by URL rewriting inside a subdirectory though (I'm only rewriting to the root's index.php).

(Oh, and you'll have to make sure Xdebug doesn't conflict with FPM on your system, out of the box they want to use the same ports.)

share|improve this answer
This is a good solution but unfortunately this approach does not work when urls containing .php need to be rewritten e.g. for WordPress multisite. /ms_blog_1/wp-admin/load-scripts.php?blah=blah – Phil_1984_ Mar 8 at 7:48
For me, just adding an override DirectoryIndex index.html in the vhost in question fixed it. If I have DirectoryIndex index.php, then it seems other PHP files end up giving the 'File not found' and 'Primary script unknown' error. In my case, I have an index.html but a php file test.php. – geerlingguy Jun 3 at 4:06

This is what I've got. It seems to work OK. I put Drupal in a subdirectory and its rewrites work, directory indexes work, and PATH_INFO works.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$
RewriteCond %2 -f
RewriteRule . fcgi:// [L,P]
RewriteOptions Inherit

I've tried to do something like this without rewrites ("If" and such), but I couldn't get anything to work.

EDIT: Note that if you were to implement this as a shared hosting provider, this could be a security issue. It would allow users to pass PHP scripts to an arbitrary fcgi proxy. If you had a seperate pool for every user, that would allow for elevation of privilege attacks.

share|improve this answer

Best way to solve this is to turn on debugging logs for mod_proxy and mod_rewrite and php-fpm. In apache 2.4 you can now turn on debugging logs for specific modules only. Per-module and per-directory configuration is available in Apache HTTP Server 2.3.6 and later

Maybe you're getting a double slash on directories?

Here's what I use and it works fine:

<LocationMatch ^(.*\.php)$>
  ProxyPass fcgi://$1
share|improve this answer

All you need to do is to set:

 ProxyErrorOverride on

And do not forget to set the customer page by:

ErrorDocument 404 /path/to/error_page_file    
share|improve this answer

One thing I came across in my dealing with this issue, is that if you use the combination of:

chroot = /path/to/site
chdir = /

In your fpm pool configuration, don't pass the full path to the ProxyPass directive.

ProxyPass fcgi://$1

But -ONLY- if the pool on that port is chrooted.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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