The problem is that in a URL, # introduces the fragment, and ? introduces the query. Path components on Unix / Linux / MacOS / iOS fortunately cannot contain "/" characters (they are separated by "/" but cannot contain a slash) because that would be another pain.
Almost all characters in the file path either become part of the URL unchanged, or they are percent-encoded and URLs know that for example %20 in the percent-encoded URL is really a space character in the path.
The two exceptions are # and ?. As soon as you have a path containing # or ?, which is perfectly legal, parsing the URL will think that "?" introduces a query, and "#" introduces a fragment, so ? or # and all following characters are not part of the path, but are turned into "query" and "fragment". And you cannot escape them in the original path, because %23 is again a perfectly legal path of three characters, percent, two and three, and gets percent-escaped to %2523, and when you or the OS tries to recreate the path, this is translated to %23.
(The "?" might cause trouble in shell scripting, but inside a path it is just as legal as any other character, at least in MacOS X and iOS. Even a nul byte is legal in a path except that C code trying to handle a path as a C string will again run into trouble).
aaaa_%23_aaaa.msg
worked for me on IE8. – Hindenburg%23
works in Firefox/26, Chrome/32, Opera/12.16 and Explorer/11 (all running on Windows 7). What target browser is it failing for? – Conjoint<a href="file://attachments/aaaa_%23_aaa.msg">aaaa_#_aaa.msg</a>
In IE11 is trying to openfile://attachments/aaaa_%2523_aaa.msg
– Numismatistfile:///C:/attachments/
); otherwise, it didn't work in any browser no matter the file name. – Conjoint