Hi everyone,
I’m running into an issue with ThingWorx FileRepositoryDownloader when trying to download files that contain a # character in their name.
For example, I have a file in my repository called:
test#2.pdf
When I build the URL dynamically using encodeURIComponent, it looks like this:
https://<server>/Thingworx/FileRepositoryDownloader?download-repository=test.FileRepository&directRender=true&download-path=%2F1760338581178%2F1761219448752%2Ftest%232.pdf
However, the request always fails with:
HTTP 406 – Not Acceptable
and the response shows Content-Length: 0 from the ThingWorx Nginx server.
If I rename the file (for example to test_2.pdf), the same request works perfectly.
It seems that even though the filename is correctly encoded (%23), the FileRepositoryDownloader servlet doesn’t handle # correctly inside the download-path query string.
Has anyone else encountered this before?
i am using webgl widget to render pdf in browser..
output = "/Thingworx/FileRepositoryDownloader?download-repository=" + fileRepository + "&directRender=true&download-path=" + encodeURIComponent(path);
Is there a known workaround or a configuration change to make ThingWorx accept such filenames (without renaming them)?
Note All German characters in pdf name were causing an issue but after adding this encodeURIComponent(path) in generating pdf path all problems were resolved. special characters mean ü ö but this only file which has # hash sign is causing an issue.
Any help or confirmation would be greatly appreciated
Two ideas:
1) You could try the alternative link to download, without the FileRepositoryDownloader.
<Thingworx>/FileRepositories/myRepository/myFile.txtHTTP 406 – Not Acceptable Thanks @Rocko are you talking about platform-settings.json file? Or how can i find this configs where these all validation properties are mentioned?
no, esapi is a subdirectory in your TWX ThingworxStorage directory. There might be also something in the help about this. If this is the issue, you have to add # as an allowed character into the regular expression.
so i have used first idea which you have mentioned and with that workaround i am able to load the pdf in webView widget but it only works when there is a hash in file otherwise i am using same link. as below
if (format == "pdf" && path.endsWith("pdf")) {
if (path.includes("#")) {
output = downloadUrl;
} else {
output = "/Thingworx/FileRepositoryDownloader?download-repository=" + fileRepository + "&directRender=true&download-path=" + encodeURIComponent(path);
}
} else {
output = undefined;
}
I would like to resolve the issue properly as you have mentioned also. I ll update here if i would be able to find a real root problem and its solution.
may be question arise why two links to render pdf ? because when i click download button with the hash link then it opens the pdf in new tab of browser and without hash it downloads the pdf. Thats why i am using two different links for now..
Hi @Rocko I have found that file in esapi folder and here below in screenshot you can see that i have removed # symbol from fileName
i am still encountering same error. here are the logs
2025-10-24 10:23:31.358+0000 [L: ERROR] [O: E.c.t.s.f.ValidatingHttpRequest] [I: ] [U: Z022] [S: ] [P: ] [T: https-openssl-nio--exec-7] Error occurred while validating HTTP parameter: download-path. HTTP parameter name: download-path: Invalid input. Please conform to regex ^[a-zA-Z0-9.\-\/+=_', ¡-:]*$ with a maximum length of 2000
2025-10-24 10:23:31.358+0000 [L: ERROR] [O: E.c.q.l.c.Logger] [I: ] [U: Z022] [S: ] [P: ] [T: https-openssl-nio--exec-7] Invalid Request Exception:
2025-10-24 10:23:31.358+0000 [L: ERROR] [O: E.c.q.l.c.Logger] [I: ] [U: Z022] [S: ] [P: ] [T: https-openssl-nio--exec-7] Invalid Request Exception: No Path Was Specified
Error Logs
2025-10-24 10:31:27.319+0000 [L: ERROR] [O: E.c.t.s.f.ValidatingHttpRequest] [I: ] [U: Z0227] [S: ] [P: ] [T: https-openssl-nio--exec-2] Error occurred while validating HTTP parameter: download-path. HTTP parameter name: download-path: Invalid input. Please conform to regex ^[a-zA-Z0-9.\-\/+=_', ¡-:]*$ with a maximum length of 2000
2025-10-24 10:31:27.319+0000 [L: ERROR] [O: E.c.q.l.c.Logger] [I: ] [U: Z0227] [S: ] [P: ] [T: https-openssl-nio--exec-2] Invalid Request Exception:
2025-10-24 10:31:27.319+0000 [L: ERROR] [O: E.c.q.l.c.Logger] [I: ] [U: Z0227] [S: ] [P: ] [T: https-openssl-nio--exec-2] Invalid Request Exception: File Repository [undefined] does not exist
2025-10-24 10:31:27.338+0000 [L: ERROR] [O: E.c.t.s.f.ValidatingHttpRequest] [I: ] [U: Z0227] [S: ] [P: ] [T: https-openssl-nio--exec-5] Error occurred while validating HTTP parameter: download-path. HTTP parameter name: download-path: Invalid input. Please conform to regex ^[a-zA-Z0-9.\-\/+=_', ¡-:]*$ with a maximum length of 2000
2025-10-24 10:31:27.338+0000 [L: ERROR] [O: E.c.q.l.c.Logger] [I: ] [U: Z0227] [S: ] [P: ] [T: https-openssl-nio--exec-5] Invalid Request Exception:
2025-10-24 10:31:27.338+0000 [L: ERROR] [O: E.c.q.l.c.Logger] [I: ] [U: Z0227] [S: ] [P: ] [T: https-openssl-nio--exec-5] Invalid Request Exception: No Path Was Specified
our validation file ( i have removed # from Validator.FileName and Validator.URL ...other then that no # symbol exists in this file)
# Validation.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
#
# Then you can validate in your code against the pattern like this:
# Validator.getInstance().getValidDataFromBrowser( "Email", input );
# Validator.getInstance().isValidDataFromBrowser( "Email", input );
#
Validator.SafeString=^[\p{L}\p{N}.]{0,1024}$
Validator.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&%\\$#_]*)?$
Validator.CreditCard=^(\\d{4}[- ]?){3}\\d{4}$
Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$
# Validators used by ESAPI
Validator.AccountName=^[a-zA-Z0-9]{3,20}$
Validator.SystemCommand=^[a-zA-Z\\-\\/]{0,64}$
Validator.RoleName=^[a-z]{1,20}$
Validator.Redirect=^\\/Thingworx.*$
# Global HTTP Validation Rules
# Values with Base64 encoded data (e.g. encrypted state) will need at least [a-zA-Z0-9\/+=]
Validator.HTTPScheme=^(http|https)$
Validator.HTTPServerName=^[a-zA-Z0-9_.\\-]*$
Validator.HTTPParameterName=^[a-zA-Z0-9_]{0,32}$
Validator.HTTPParameterValue=^[a-zA-Z0-9.\\-\\/+=_', \u00A1-\uFFFF:]*$
# On entity import from a file repository. The parameter exportFileName has the name of the file which holds the entity.
Validator.HTTPParameterValue_exportFileName=^.+$
Validator.HTTPParameterValue_repositoryName=^[a-zA-Z0-9.\\-\\/+=_', \u00A1-\uFFFF:<>]*$
Validator.HTTPParameterValue_reason=^[a-zA-Z0-9.\\-\\/+=_,/:\\n@$ \u00A1-\uFFFF]*$
Validator.HTTPParameterValue_SAMLResponse=^[a-zA-Z0-9+\/=]*$
Validator.HTTPCookieName=^[a-zA-Z0-9\\-_]{0,32}$
Validator.HTTPCookieValue=^[a-zA-Z0-9\\-\\/+=_ ':]*$
Validator.HTTPHeaderName=^[a-zA-Z0-9\\-_]{0,32}$
Validator.HTTPHeaderValue=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ %\$ \u00A1-\uFFFF'"]*$
Validator.HTTPHeaderValue_cookie=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_|% ]*$
Validator.HTTPHeaderValue_if-none-match=^.*$
Validator.HTTPHeaderValue_if-range=^.*$
Validator.HTTPHeaderValue_referer=^([a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]|%[a-fA-F0-9]{2})*$
Validator.HTTPContextPath=^[a-zA-Z0-9.\\-_]*$
Validator.HTTPPath=^[a-zA-Z0-9.\\-_]*$
Validator.HTTPQueryString=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ](1,50)$
Validator.HTTPURI=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$
Validator.HTTPURL=^.*$
Validator.HTTPJSESSIONID=^[A-Z0-9]{10,30}$
# Validation of file related input
Validator.FileName=^[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{0,255}$
Validator.DirectoryName=^[a-zA-Z0-9:\\\\!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{0,255}$
not sure why you removed # from the pattern, if your filename has a #.
Your filename must match the regular expression. According to the error, it does not and therefore is rejected.
Adapt the filename to match the regex, or change the regex.
# is part of regex. I have removed it just for test but now its there is regex and then it should work but its not working and file name is test#2.pdf which is according to our regex. so far i have no clue why its not working.
