20

I have a Spring MVC application running on Tomcat8. Once in a day or two I get an exception in my log file

15-Jun-2016 10:43:39.832 INFO [http-nio-8080-exec-50] org.apache.coyote.http11.AbstractHttp11Processor.process Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
 java.lang.IllegalArgumentException: Invalid character (CR or LF) found in method name
    at org.apache.coyote.http11.AbstractNioInputBuffer.parseRequestLine(AbstractNioInputBuffer.java:228)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1502)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1458)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

does anybody have an idea what this might be?

Vadim Dissa
  • 961
  • 3
  • 13
  • 32
  • 1
    Looks like incoming HTTP request header is malformed. As error message tells you, the request header contains prohibited character in the HTTP method name (end of line), thus request parser fails with exception. So it's not an issue in your code. You can either ignore it or ask the sender to check request validity. – Vladimir Vagaytsev Jun 15 '16 at 13:28
  • @Vladimir Vagaytsev - request is from Web & we have LB setup with nginx. On the server it throws the above error and throws Bad Gateway. scalescale.com/tips/nginx/502-bad-gateway-error-using-nginx didn't help :( – Narendra N Jun 17 '16 at 12:12
  • I believe, this exception has to do more with the SSL Setup, as the same (well, almost similar) war works on stage machines - where we access with http - Whereas the test Production setup (using https) is where we are facing this issue. Have to check our nginx configuration. In case, you have found the fix - do, let me know :) – Narendra N Jun 17 '16 at 12:37
  • Hi VadOs, Is your tomcat running in the cloud machine? if yes, please refer - (http://cyber4.org/three-legged-pig/captain-were-being-scanned-by-an-alien-ship/) and (https://confluence.atlassian.com/confkb/confluence-log-has-java-lang-illegalargumentexception-invalid-character-cr-or-lf-found-in-method-name-827127067.html) – Ramesh Subramanian Jun 29 '16 at 06:02
  • Guys, did you achieve any progress? – xenteros Jul 29 '16 at 09:22

6 Answers6

41

This error is caused by malformed HTTP request. In most cases this message is misleading because this error usually happens when you are trying to access unsecured page through https. Tomcat doesn't know that incoming request is encrypted and is trying to interpret this request as plain, unsecured http request.

This is how it could look in logs:

Standard, proper HTTP request (http://localhost:8080)

Received [GET /index.html HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: pl,en-US;q=0.8,en;q=0.6
Cookie: Idea-xxxxx; JSESSIONID=3dxxxxx

] 

HTTPS request (https://localhost:8080)

Received [¹µHÄ;ß!P@<¿
                                                                                                                                #|vFBb-Ëiø/5
jÿ

                   hhttp/1.1uP
                               
] 

As you can see in second request, there are unknown chars instead of proper HTTP method name (e.g. GET)

So if your server has no SSL configuration and error occurs "once in a day or two", then probably someone is trying to reach your website through https (probably some kind of bot)

Eventually someone is trying to send nonsecured but malformed plain HTTP request (through his own application - bot or other custom client).

Maciej Marczuk
  • 3,593
  • 29
  • 28
  • 3
    Does this error causes tomcat to stops working ??I am getting this exception many times and my tomcat is getting stoped at regular interval... – KJEjava48 Apr 03 '17 at 10:48
3

Just add this problem too with springboot. I was using a HTTPS url but my local server wasn't using SSL, so I switched the url to HTTP and it worked.

Maelig
  • 2,046
  • 4
  • 24
  • 49
1

Recheck the request sent. If the endpoint is not https enabled, pass the request with http.

Sarat Chandra
  • 5,636
  • 34
  • 30
1

I also faced the same issue with HTTP POST Request- The problem was "JSON data was not correct". I had an enum attribute in class which i was passing wrong (spelling mistake) in object. And i was getting this exception.

Bhupendra Kumar
  • 179
  • 3
  • 7
1

I encountered this same error and it can have absolutely nothing to do with your Tomcat configuration. It drove me crazy trying to find the error. I was serving multiple applications from six domains with only one of the domains producing the Proxy Error 502. The 'Invalid character' message is then found in Tomcat's log catalina.out:

Apr 18, 2018 10:31:06 AM org.apache.coyote.http11.AbstractHttp11Processor process
INFO: Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
java.lang.IllegalArgumentException: Invalid character (CR or LF) found in method name
        at org.apache.coyote.http11.InternalAprInputBuffer.parseRequestLine(InternalAprInputBuffer.java:177)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:992)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
        at org.apache.tomcat.util.net.AprEndpoint$SocketWithOptionsProcessor.run(AprEndpoint.java:2454)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

In my case, I am sending requests to Tomcat applications from Apache httpd using a proxy. The proxy directives are used within httpd's virtual host, normally configured in /etc/httpd/conf.d/virtualhosts.conf. The proxy first redirects any unencrypted http requests received on port 80 to port 443.

<VirtualHost *:80>
  ServerName www.domain1.com
  ServerAlias domain1.com *.domain1.com
  Redirect permanent / https://domain1.com/
</VirtualHost>

The redirected request is then handled as a normal incoming encrypted https request.

The incorrect configuration. DO NOT COPY THIS!

  <VirtualHost *:443>
      ServerName www.domain1.com
      ServerAlias domain1.com *.domain1.com
      ProxyRequests off
      ProxyPreserveHost on
      CustomLog "/etc/httpd/logs/domain1ssl.log" "%h %l %u %t \"%r\" %>s %b"
      ErrorLog "/etc/httpd/logs/domain1ssl_error.log"
      SSLEngine on
      SSLProxyEngine on
      SSLCertificateFile /etc/pki/tls/certs/domain1.com.crt
      SSLCertificateKeyFile /etc/pki/tls/private/domain1.key
      SSLCertificateChainFile /etc/pki/tls/certs/ca-bundle-domain1.crt
      ProxyPass / https://domain1.com:8081/
      ProxyPassReverse / https://domain1.com:8081/
    </VirtualHost>

Note the two lines:

ProxyPass / https://domain1.com:8081/
  ProxyPassReverse / https://domain1.com:8081/

The directives are telling Apache to send the request to the process listening on port 8081 as an encrypted request. This was typo on my part. The protocol should be http. Tomcat is not handling encryption, httpd is handling encryption. So Tomcat is receiving an encrypted request on a non-encrypted connector resulting in the 'Invalid character' error exceptionally well explained in Maciej Marczuk's (https://stackoverflow.com/users/1545775/maciej-marczuk) answer. Many thanks for cluing me in to finding my typo.

The proxy directives should be:

ProxyPass / http://domain1.com:8081/
  ProxyPassReverse / http://domain1.com:8081/

Hope this helps someone. Cheers.

Ted Spradley
  • 3,414
  • 3
  • 22
  • 26
0

This error may occur because of bad port.

Actually, notice that if you want accept throw HTTPS, default Tomcat port is 8443 : https://localhost:8443

when you change connector and keystore but still fetching with 8080 instead of 8443

Community
  • 1
  • 1
hadf
  • 279
  • 2
  • 5
  • 15
  • 1
    This is good factual information, but it wasn't written in a way that answers the question at hand. Please delete this answer and add it as a comment to the most appropriate answer. – Edwin Buck Jul 18 '17 at 18:38
  • 1
    I don't agree. I posted this comment because I had exactly the same error due to the bad port – hadf Jul 19 '17 at 20:11
  • That's fine, but please rewrite your answer to include the question in some manner. Your response could also read "Notice that if you want accept throw HTTP, default Tomcat port is 8080" and it would contain the same information: information about default ports. Not relating that information to his problem is why I say it doesn't answer the question. The fact is correct, but so is the fact that saying FTP's default port is 21. Until you show how the fact and the problem are related, you're not answering the question, you are just saying facts. – Edwin Buck Jul 20 '17 at 18:23