Negotiation: Discovered File(s) Matching Request: None Could Be Negotiated

Posted June 24, 2011 at 9:30 AM by Ben Nadel

Tags: ColdFusion, Work

Yesterday, I lost at least two hours trying to figure out why my local copy of a website was throwing 404 (File Not Found) errors. We had just implemented some URL rewriting on the production site and things appeared to be working fine. On my local computer, however, the URL rewriting would only work for some URLs. After a lot of Googling, a little bit of a meltdown, and walk around the block to clear my head, I finally figured out what was going wrong: MultiViews.

For this particular website, we were using Apache to create a more resource-oriented URL scheme. So, where we used to have URLs that looked like this:

/users.cfm?action=view&id=15

... we were going to be moving to a URL scheme that looked more like this:

/users/15/view/

For the majority of URLs in the application, this was working fine. But for a few URLs, this came back as a 404 File Not Found error. When I looked in the Apache error logs, I kept seeing log items like this:

[Thu Jun 23 16:55:06 2011] [error] [client 127.0.0.1] Negotiation: discovered file(s) matching request: /Sites/something.com/users (None could be negotiated).

My experience with the Apache HTTP server is somewhat limited; as such, this error didn't really mean anything coherent to me at the time. And, much of my Googling wasn't really yielding anything too valuable. Finally, however, I did come across a threaded discussion that mentioned "MultiViews". On the Apache website, the effect of Multiviews, as listed under Content Negotiation, is as follows:

If the server receives a request for /some/dir/foo, if /some/dir has MultiViews enabled, and /some/dir/foo does not exist, then the server reads the directory looking for files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's requirements.

This is exactly what was happening! When the user requested the non-existent URL:

/users/15/view/

... Apache was finding this physical file on a per-directory basis:

/users.cfm

... and then using Content Negotiation to try and figure out which file it should served up based on the request headers. And, since I didn't have any file types configured for content negotiation, Apache didn't know how to respond and just returned a 404.

When I checked in my Virtual Host configuration, sure enough, MultiViews was enabled:

  • Options Indexes FollowSymLinks MultiViews

The moment I removed the MultiViews option:

  • Options Indexes FollowSymLinks

... everything started working fine.

This goes to show you how bad it is to simply enable settings when you are not sure what they do. I've grown to love my Apache server; but, clearly, there is so much more that I need to learn about it. When it works, it works; but, when it doesn't, I have no idea what's going on.



Reader Comments

Jun 24, 2011 at 9:39 AM // reply »
148 Comments

Yeah, these Apache configurations can be rather arcane.


Jun 24, 2011 at 9:43 AM // reply »
11,246 Comments

@Lola,

I was not in a good place yesterday :) I swear, I almost just lost it!!


Jun 24, 2011 at 10:04 AM // reply »
9 Comments

One way to avoid these Apache default directives from affecting you is to always set your DocumentRoot to an empty non-public directory.

Then you can define virtual host files with concise rules, typically in the other or extra directories. The very last lines of tour httpd.conf file point to one of these folders and loads all .conf files located there.

A vhost file typically only requires two sections: VirtualHost, where the site's domain, logs, etc. are setup and a Directory section with all your rules.


Jun 24, 2011 at 10:12 AM // reply »
11,246 Comments

@Claude,

I think this (what you are saying) is what my Apache config actually had in it right out of the box. It set some root directory and turned off all options. It was totally *me* who added MultiViews in the Virtual Host option set. I think I just turned on everything that was there since I had no idea what any of it did :)


Jun 24, 2011 at 10:47 AM // reply »
9 Comments

Yes, I looked at the original* http.conf files on my iMac and Linux server and Mac and those directives are there by default for the DocumentRoot. Maybe you copied those settings elsewhere without reading up on them. :)

*Call me crazy, but I do keep a copy of the original for most server configs.


Jun 24, 2011 at 10:49 AM // reply »
11,246 Comments

@Claude,

Yeah, I probably did :) I come from an IIS background (not that I ever knew IIS all that well) and I think I was just thrilled that I could get Apache to work at all!


Jun 24, 2011 at 10:58 AM // reply »
9 Comments

I know how you feel, I'm still learning this stuff. Sometimes even on live servers!


Jun 24, 2011 at 12:34 PM // reply »
2 Comments

I am also curious as to your use of follow symlinks too ? :]


Jun 24, 2011 at 2:02 PM // reply »
11,246 Comments

@Brad,

I tried to remove the FollowSymLinks and it seemed to break the URL Rewriting. I just did a bit of Googleing and found:

"Options +FollowSymLinks is an Apache directive, prerequisite for mod_rewrite"

So, it must be doing something important.


Jun 24, 2011 at 2:11 PM // reply »
2 Comments

Interesting, I do not use that at all, unless I need to link directors (symlink) as I have no need. My computer, dev and production environments all run on Ubuntu though. Windows is increasingly becoming enigmatic to me.

SymLinks is something windows doesn't really have, afaik so I was curious as to why it might be needed.

For sake of argument this is what my personal environment looks like for a random site. As I do not care about local security really, it makes things quick.

<Directory /home/brad/workd/hv/hv >
Allow from all
</Directory>

I then have my rewrite in .htacess which also doesn't use follow symlinks.

for simplicity it's simply

RewriteEngine on
RewriteRule ^(.*)$ index.php/$1 [L]

Super curious. Maybe that's what the docs mean by having it

The rewrite engine may be used in .htaccess files and in <Directory> sections, with some additional complexity.

So, since I am using .htaccess I don't need it. You may be using directory so you do ?


Jun 25, 2011 at 12:35 AM // reply »
4 Comments

instead of ?action=view&id=15
I use ones like ?view=15
seems a bit simpler to may, any thoughts people?


Jun 26, 2011 at 3:26 PM // reply »
272 Comments

@David, we Mac folks tend to separate target and action. It's built right into Xcode 4, in fact. To establish a target/action connection, you use drag-and-drop in the Interface Builder window. Drag from a control to the setter method of a value you want it to control, for example.

In many ways, it's like the CSS cascade. That's a REALLY arcane analogy, so let me explain:

Suppose you've defined class="major" hotlinks to be in a larger font than those that don't have that class. You can also define that all hotlinks to :hover in some cool way unrelated to font size. The class="major" hotlinks will highlight that way too, because you've separated target and action.

By defining ?action=view&id=28, Ben has allowed his code to do cfif IsDefined("URL.id") and establish identity in a way that can be shared across numerous actions. So the complexity is encoded into the data structure (ampersand-delimited list of equals-delimited lists), allowing the underlying code to be simpler.


Jun 27, 2011 at 4:50 AM // reply »
4 Comments

Not really sure I see the comparison between this situation and multi-inheritence in css.

In my mind this situation is closer to calling a method on a static object and passing it the ID of the instance to perform the relevant action on:
widget.cfm?Update=123&...
seems very similar, from a programming syntax point of view, to:
widget.Update(123,...)
and the are often times an action may not need an ID, like creating a new object.

Just seems that using 2 variables is not necessary in this circumstance.


Jun 27, 2011 at 3:43 PM // reply »
272 Comments

@David, well, I said it was an arcane analogy.

The idea is that, by not hardwiring targets to actions up front, you allow reuse of parts and reduce combinatorial explosion. In the CSS example, combinatorial explosion would have been defining a.major, a.major:hover, a.minor, a.minor:hover, etc, with plenty of redundancy across the selectors. But defining only a.major and a:hover, you reuse the :hover properties without redundancy. No class="minor" needed. By doing less, more gets done. Probably faster too.

Perhaps a better analogy would be normalization of a relational database. Separating target and action is logical atomism. Making "view" imply both action and id, you are denormalizing the interface. As all theorists acknowledge, sometimes it's just practical to denormalize, but the converse is also true. Sometimes it's just practical to normalize.


Jun 27, 2011 at 4:41 PM // reply »
4 Comments

Again not really seeing how this relates to normalization, the core aspect of normalization is elimination of redundant and/or duplicate data. Another very small benefit of my style is it can allow calling 2 methods in 1 http call, ie: widget.cfm?Delete=#ThisID#&View=#NextID# , I don't use it that way very often, but it can be handy in some circumstances.


Jun 28, 2011 at 9:55 PM // reply »
11,246 Comments

@Brad,

To be honest, some of what you are saying goes over my head. I am not that great at Apache (I'm running on Mac locally, FYI). It might have to do with the way I have the core httpd config set up?

@David,

I think what Steve is saying is that you can break apart different aspects of the routing. So, for example, if I use Action and ID, I can apply uniform security (for example) before I even get to the part of the page where the "ID" comes into effect.

For example, I might have something like this in my request handling (pseudo code):

  • <cfif not userCanPerformAction( user, url.action )>
  • <cfthrow type="AccessDenied" />
  • </cfif>

By using a uniform action variable, I can use a bit of a simpler divide-and-conquer approach to routing rather than having to figure out special variables for each.

Of course, this all depends on the underlying framework you have to be using. I use a front-controller style workflow where most things go through index.cfm. But, if you use a page-controller style workflow where things typically all different top-level pages, I see no reason again your approach.


Jun 29, 2011 at 10:30 AM // reply »
1 Comments

Thank you for this post!

I don't use WebDav generally, but was setting it up on my Ubuntu box at home to allow me to synchronize my KeePass database more easily. When I'd try to save any changes to the webdav area I was getting "404 file not found" and it left me with a KeePass.kdbx.tmp file. Removing "MultiViews" fixed it.

I would never, ever have found this on my own.

I'm leaving this (admittedly mostly extraneous) here in case other KeePass users come googling.


Jul 13, 2011 at 9:25 PM // reply »
11,246 Comments

@Tim,

My pleasure! I posted this up so hopefully people wouldn't have to bang their heads against the wall. I make no joke when I say that I lost over 2 hours of time just trying to figure this baby beast out!


Jul 14, 2011 at 5:16 AM // reply »
1 Comments

A little Addendum:

For those people, who have no access to the Apache Configuration (as is the case with my Provider, i cant turn off MultiViews):

Simply avoid filenames that match the virtual directory names.

In my Case:
www.mycustomersdomain.at/kunden
was rewritten to
www.mycustomersdomain.at/kunden.php?page=kunden
and resulted in above mentioned error.

Renaming kunden.php to kundenseite.php resolved the problem, as apache had nothing left to negotiate!

THX to Ben for this post, it pointed my the right direction - Very helpful!


Jul 20, 2011 at 10:46 AM // reply »
11,246 Comments

@Michael,

Excellent tip! Thanks. I hadn't even thought of making that recommendation.


Feb 29, 2012 at 7:04 PM // reply »
1 Comments

Thanks for this post :).

Today, it was very useful for me.


Mar 30, 2012 at 11:35 AM // reply »
1 Comments

Thank you, you just solved the problem with syncing my mobile with my dav server. :-)


Apr 14, 2012 at 7:17 AM // reply »
1 Comments

Thanks a million Ben!

I don't want to think about the time I'd have lost if this post didn't pop in my google search !!

And so well explained !

Thanks again!

John.


Apr 14, 2012 at 1:47 PM // reply »
11,246 Comments

@Jonathan,

No problem! As someone [me] who is relatively new to Apache, it's super powerful, but definitely throws a number of curve-balls if the configuration is not quite right! I know enough to get things done; but, I'd love to have a better handle on the Web Server layer so that I could tap into even more of the power.


May 5, 2012 at 7:44 AM // reply »
1 Comments

Thanks a lot !
You saved my afternoon :D


May 10, 2012 at 5:50 AM // reply »
1 Comments

Thank you! Everything works now ;)


Jul 26, 2012 at 2:30 PM // reply »
1 Comments

Very often when I "google" a problem, your posts are first to appear. More often than not, you have a solution. Thank you for posting your struggles to help those of us who have less tolerance to struggling. ;-)


Aug 26, 2012 at 12:32 PM // reply »
1 Comments

Wow, you just saved me a tremendous amount of time and puzzlement. Many thanks.


Aug 31, 2012 at 12:40 PM // reply »
1 Comments

Thanks! Saved me a lot of time and frustration!


Oct 2, 2012 at 8:10 AM // reply »
1 Comments

Thanks so much for this. I just did a fresh install of ubuntu 12.10 and have almost gotten my system to where I want it to be only try to login to one of my dev sites to get this. Its strange though that I should be getting this error as having Multiviews has never caused me any problems. Anyway off to clock some billable hours :)


Oct 10, 2012 at 11:31 AM // reply »
1 Comments

Thanks man, you safe my ass


Oct 13, 2012 at 9:10 AM // reply »
1 Comments

Thank you!
Same problem, googled the error.log-message, first hit: your straightforward blog entry. :-)


Oct 20, 2012 at 8:48 AM // reply »
1 Comments

Thank you!
Just put this line in my Wordpress .htaccess:

  • Options -MultiViews

Now I can access both different pages: /page and /page.php


Nov 25, 2012 at 4:50 AM // reply »
1 Comments

Thank you very much for this article.


Jan 12, 2013 at 12:13 AM // reply »
1 Comments

Hey Ben, Thanks a lot! You really saved my day!! :)


Mar 9, 2013 at 7:13 AM // reply »
3 Comments

Hi Ben,

I had a similar error and was confused why, in development everything worked fine yet on my new testing server, all requests other than the home page failed. Thanks for the link.

I had exactly the same issue. Now to find out what mod was enabled on my dev box, that wasn't on my testing box.

Matt


Apr 3, 2013 at 12:11 PM // reply »
1 Comments

Thank you VERY much! I was tearing my hair out on this one. We have our site set up to redirect 404s to our homepage. It was working on ANY other URL I entered that was bogus, but this ONE that was legit was throwing an immediate 404, not even running my site code. I knew it had to be Apache but had no idea what the errors meant. You saved me hours, thank you!!


Apr 4, 2013 at 9:33 AM // reply »
11,246 Comments

I'm glad this is helping people! It's a shame when little config issues like this will wastes HOURS of time!



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 24, 2013 at 9:11 AM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Brandon, Hi, No, I haven't been able to do that. I have just kept it as it is. ... read »
May 23, 2013 at 9:52 PM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Muhmmadibn Did you figure out a solution to launching PDFs? I am running into the same issues myself. There is no way to close the PDF or go back once you launch it. Thanks in advance! ... read »
May 23, 2013 at 6:06 PM
The Girl Who Broke My Heart, And Made Me A Better Person
Good day,ladies and gentle men, my name is Dr AMADI the great spell caster in Africa, i have help so many people for different kind of problems,who say there is no solution to problems on earth, that ... read »
May 23, 2013 at 4:26 PM
ColdFusion QueryAppend( qOne, qTwo )
@Heather, Glad people are still getting value out of this! ... read »
May 23, 2013 at 3:49 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, I meant the code at the bottom (not the video). I did try to experiment with an intermediary variable, like: value = users.id[ i ]; arrayContains( userIDs, value ); ... but t ... read »
May 23, 2013 at 11:06 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Are you talking about As Number: YES As String: YES As Java: YES? If so, that's with 3 different ways of referencing the constant 1, not users.id[1]. Query object references(*) are what seem ... read »
May 23, 2013 at 9:55 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dan, According to the CF Admin, I'm running Java "1.6.0_45". As far as the DB column, in the database it's an INT. I'll see if I can dig into what CF sees it as. @WebManWalking, But h ... read »
May 23, 2013 at 9:49 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, I think the problem is that we're used to loose typing in ColdFusion, like JavaScript. If a value is a number but it's needed in an expression to be a string, noooo problem. I've encountered ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools