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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
260 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 »
260 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 ;)



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
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 21, 2012 at 1:58 AM
Updated: Converting A ColdFusion Query To CSV Using QueryToCSV()
Hi Ben, why do you need to have so many double quotes when adding the field and field name to the row data? ----------------------------------------- <cfset LOCAL.RowData[ LOCAL.ColumnIndex ] = ... read »
AXL
May 21, 2012 at 1:24 AM
URL Rewriting And ColdFusion's WriteToBrowser Image Functionality (CFFileServlet)
@Mounir, Open your lower case URL Rewrite rule and add the following condition. Condition input: {REQUEST_URI} Check if input string: Does Not Match the Pattern Pattern: ^/CFFileServlet/_cf_ca ... read »
May 20, 2012 at 4:28 AM
Understanding The Complex And Circular Relationships Between Objects In JavaScript
@Will Vaughn I tried your javascript example but got this error:- foo.print is not a function ... read »
May 19, 2012 at 5:37 AM
A Graphical Explanation Of Javascript Closures In A jQuery Context
Thanks for this article, but I fear you missed an important point. If variables in the outer context change, these changes affect the inner anonymous functions as well. That means: if you change the ... read »
May 18, 2012 at 3:39 PM
Parsing CSV Data With An Input Stream And A Finite State Machine
Can you use file upload button with this? and read live? or does the file have to already be on the server saved? ... read »
May 18, 2012 at 1:06 AM
VIRGO (Aug. 23-Sept. 22): Dead On The Money!
A friend of mine and I were arguing about astrology and she told me that he believes in astrology. She hasn't provided me with any evidence that the belief makes any sense to me. She she been telling ... read »
May 17, 2012 at 11:32 PM
Using ColdFusion to Handle 404 Errors (Page Not Found) On Development Server
Very easy the configuration. I read a lot pages and I can't find the solution. I open the administrator and change this Administrator/server settings/Error Handlers/Missing Template Handler and p ... read »
May 17, 2012 at 3:13 PM
LOCAL Variables Scope Conflicts With ColdFusion Query of Queries
I never cease to be amazed that almost EVERY random CF issue I come across lands me on your site. Thank you for documenting your findings for the world. ... read »