CURL ERROR: Recv failure: Connection reset by peer - PHP Curl
Asked Answered
P

11

119

I'm having this strange error, CURL ERROR: Recv failure: Connection reset by peer

This is how it happens, if I did not connect to the server and all of a sudden trying to connect to the server via CURL in PHP I get the error. When I run the CURL script again the error disappears and then works well the whole time, if I leave the remote server idle for about 30mins or reboot the remote server and try to connect again, I get the error again. So it seems like the connection is idle and then all of sudden the server wakes up and then works and then sleeps again.

This is how my CURL script looks:

$url = Yii::app()->params['pdfUrl'];
$body = 'title='.urlencode($title).'&client_url='.Yii::app()->params['pdfClientURL'].'&client_id='.Yii::app()->params['pdfClientID'].'&content='.urlencode(htmlentities($content));

$c = curl_init ($url);
$body = array(
    "client_url"=>Yii::app()->params['pdfClientURL'],
    "client_id"=>Yii::app()->params['pdfClientID'],
    "title"=>urlencode($title),
    "content"=>urlencode($content)
);
foreach($body as $key=>$value) { $body_str .= $key.'='.$value.'&'; }
rtrim($body_str,'&');

curl_setopt ($c, CURLOPT_POST, true);
curl_setopt ($c, CURLOPT_POSTFIELDS, $body_str);
curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($c, CURLOPT_CONNECTTIMEOUT , 0);
curl_setopt ($c, CURLOPT_TIMEOUT  , 20);

$pdf = curl_exec ($c);
$errorCode = curl_getinfo($c, CURLINFO_HTTP_CODE);
$curlInfo = curl_getinfo($c);
$curlError = curl_error($c);

curl_close ($c);

I'm totally out of ideas and solutions, please help, I'll appreciate it!!!

If I verbose the output to see what happens using

curl_setopt ($c, CURLOPT_VERBOSE, TRUE);
curl_setopt($c, CURLOPT_STDERR, $fp); 

I get the following

* About to connect() to 196.41.139.168 port 80 (#0)
*   Trying 196.x.x.x... * connected
* Connected to 196.x.x.x (196.x.x.x) port 80 (#0)
> POST /serve/?r=pdf/generatePdf HTTP/1.1
Host: 196.x.x.x
Accept: */*
Content-Length: 7115
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

* Recv failure: Connection reset by peer
* Closing connection #0
012 20:23:49 GMT
< Server: Apache/2.2.15 (CentOS)
< X-Powered-By: PHP/5.3.3
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=UTF-8
< 
* Closing connection #0

I've added in the following toe remove the default header and still no luck:

curl_setopt ($c, CURLOPT_HTTPHEADER, array( 'Expect:' ) );

> Accept: */* Content-Length: 8414 Content-Type:
> application/x-www-form-urlencoded
> 
> * Recv failure: Connection reset by peer
> * Closing connection #0 r: Apache/2.2.15 (CentOS) < X-Powered-By: PHP/5.3.3 < Connection: close < Transfer-Encoding: chunked <
> Content-Type: text/html; charset=UTF-8 < 
> * Closing connection #0
Postconsonantal answered 23/4, 2012 at 17:55 Comment(18)
What happens when you go to this URL in your browser?Punk
@tandu - I can't add the whole url to the address bar, since the content is a lot of HTML text. But when I add the url to the browser without the POST values the browser opens the page finePostconsonantal
The URL is http or https? When using HTTPs you should ensure CURL is prepared to handle it using CURLOPT_SSL_VERIFYPEER as false.Smile
@Smile - The URL is https, strange that if I execute it first time only I get error and 2nd time it works. I added this : curl_setopt ($c, CURLOPT_SSL_VERIFYPEER , false); now i need to wait before I can test againPostconsonantal
@Smile - No it also did not do the trickPostconsonantal
@Roland There is also a CURLOPT_SSL_VERIFYHOST, please try setting it to false as well.Smile
@Smile - No also still the same mesages as in post above.Postconsonantal
@Roland: Please set an empty "Expect" header in your code to overwrite cURLs default. See w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3 for details of the behavior if you are sending 100-continueBile
@JensBradler - I've added in curl_setopt ($c, CURLOPT_HTTPHEADER, array( 'Expect:' ) ); and still the same problemPostconsonantal
@Roland: Are you able to test cURL on a shell?Bile
@JensBradler - Unfortunately not, what puzzles me is that only the first time the connection gets closed and then after that all works, I've added more Ram to the VPS server as well, so it seems like the server is sleeping and then wakes up with the first curl connection and then works perfectly after that, when server is inactive for long time then it does the whole scenario againPostconsonantal
@Roland: Please try to increase the connect timeout: curl_setopt ($c, CURLOPT_CONNECTTIMEOUT , 10);Bile
@JensBradler - Changed it to 10, and still the same, I had curl_setopt ($c, CURLOPT_CONNECTTIMEOUT , 0); which means wait indifinitely and that also did not make a changePostconsonantal
Is there a firewall between the devices?Israelitish
@Israelitish - No Firewalls I'm aware off, SELinux currently not installedPostconsonantal
Try first requesting a GET of the page you're planning to POST to. this recently got my curl program running again.Gerrygerrymander
Do you see anything in the remote server logs when you make the failed requests?Lilienthal
Please let me know how you solved this issue, i'm sending request to RESt API. But i'm getting same error. Please help meQuadrilateral
B
144

Introduction

The remote server has sent you a RST packet, which indicates an immediate dropping of the connection, rather than the usual handshake.

Possible Causes

A. TCP/IP

It might be a TCP/IP issue you need to resolve with your host or upgrade your OS most times connection is closed with remote server before it finished downloading the content resulting in Connection reset by peer.....

B. Kernel Bug

Note that there are some issues with TCP window scaling on some Linux kernels after v2.6.17. See the following bug reports for more information:

https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.17/+bug/59331

https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.20/+bug/89160

C. PHP & CURL Bug

You are using PHP/5.3.3 which has some serious bugs too ... I would advise you to work with a more recent version of PHP and CURL

https://bugs.php.net/bug.php?id=52828

https://bugs.php.net/bug.php?id=52827

https://bugs.php.net/bug.php?id=52202

https://bugs.php.net/bug.php?id=50410

D. Maximum Transmission Unit

One common cause of this error is that the MTU (Maximum Transmission Unit) size of packets travelling over your network connection has been changed from the default of 1500 bytes. If you have configured a VPN this most likely must changed during configuration

D. Firewall: iptables

If you don't know your way around these guys they can cause some serious issues .. try and access the server you are connecting to check the following

  • You have access to port 80 on that server

Example

 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT`
  • The Following is at the last line not before any other ACCEPT

Example

  -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited 
  • Check for ALL DROP, REJECT and make sure they are not blocking your connection

  • Temporary allow all connection as see if it foes through

Experiment

Try on a different server or on a remote server ( So many free cloud hosting online) and test the same script. If it works then my guesses are correct ... You need to update your system

Others Code Related

A. SSL

If Yii::app()->params['pdfUrl'] is a url with https not including proper SSL settings can also cause this error in old version of curl

Resolution: Make sure OpenSSL is installed and enabled then add this to your code

curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);
Bowler answered 27/4, 2012 at 11:35 Comment(8)
The problem seems to have been sorted, but will check in the next few days before I give an answer. What I did was the following, but I do not understand why this seems to have sorted the issue. I ssh'd to the machine ran this command sudo iptables -L and then sudo service iptables stop and then sudo service iptables start, when I ran sudo service iptables stop it flushed the iptables which I never used and all of a sudden the problem resolved. The iptables did not have information in. Do you know perhaps why this solved the problemPostconsonantal
So there is a firewall :) It is probably enforcing session timeouts differently than the web server.Israelitish
Am not sure .. i had the problem once ... after almost killing myself i just upgraded and everything worked fine .... This thing can be crazy you know .. Am Glad i was able to solve your problemBowler
@Bowler - I'll confirm if it really worked after a few days, and get back to you guysPostconsonantal
@Roland .. ok i'll wait .. i would be happy to assist if you have any more issueBowler
"The remote server has sent you a RST packet", how do you know?Exonerate
@Bowler - Thanks for the help, eventually what solved my problem was by implementing it on a different server and that somehow solved the problem, thanks for really going out of your way to helpPostconsonantal
In my case, ping worked, telnet worked, but http requested between two kubernetes clusters on connected vnets (through host:nodeporta) wasn't working. The solution... ask to the 3-4 teams that are managing security for production environment in my company, FIREWALL RESTRICTION. The communications were blocked. This gave me the hint to start pushing tickets. Thanks a lot.Dishcloth
A
20

Normally this error means that a connection was established with a server but that connection was closed by the remote server. This could be due to a slow server, a problem with the remote server, a network problem, or (maybe) some kind of security error with data being sent to the remote server but I find that unlikely.

Normally a network error will resolve itself given a bit of time, but it sounds like you’ve already given it a bit of time.

cURL sometimes having issue with SSL and SSL certificates. I think that your Apache and/or PHP was compiled with a recent version of the cURL and cURL SSL libraries plus I don't think that OpenSSL was installed in your web server.

Although I can not be certain However, I believe cURL has historically been flakey with SSL certificates, whereas, Open SSL does not.

Anyways, try installing Open SSL on the server and try again and that should help you get rid of this error.

Acescent answered 30/4, 2012 at 18:0 Comment(0)
C
7

I faced same error but in a different way.

When you curl a page with a specific SSL protocol.

curl --sslv3 https://example.com

If --sslv3 is not supported by the target server then the error will be

curl: (35) TCP connection reset by peer

With the supported protocol, error will be gone.

curl --tlsv1.2 https://example.com
Carleton answered 19/3, 2018 at 19:44 Comment(1)
It might be sufficient to just switch from http and https, if the server is configured to only respond to https.Dowdell
R
5

So what is the URL that Yii::app()->params['pdfUrl'] gives? You say it should be https, but the log shows it's connecting on port 80... which almost no server is setup to accept https connections on. cURL is smart enough to know https should be on port 443... which would suggest that your URL has something wonky in it like: https://196.41.139.168:80/serve/?r=pdf/generatePdf

That's going to cause the connection to be terminated, when the Apache at the other end cannot do https communication with you on that port.

You realize your first $body definition gets replaced when you set $body to an array two lines later? {Probably just an artifact of you trying to solve the problem} You're also not encoding the client_url and client_id values (the former quite possibly containing characters that need escaping!) Oh and you're appending to $body_str without first initializing it.

From your verbose output we can see cURL is adding a content-length header, but... is it correct? I can see some comments out on the internets of that number being wrong (especially with older versions)... if that number was to small (for example) you'd get a connection-reset before all the data is sent. You can manually insert the header:

curl_setopt ($c, CURLOPT_HTTPHEADER, 
   array("Content-Length: ". strlen($body_str))); 

Oh and there's a handy function http_build_query that'll convert an array of name/value pairs into a URL encoded string for you.

All this rolls up into the final code:

$post=http_build_query(array(
  "client_url"=>Yii::app()->params['pdfClientURL'],
  "client_id"=>Yii::app()->params['pdfClientID'],
  "title"=>$title,
  "content"=>$content));

//Open to URL
$c=curl_init(Yii::app()->params['pdfUrl']);
//Send post
curl_setopt ($c, CURLOPT_POST, true);
//Optional: [try with/without]
curl_setopt ($c, CURLOPT_HTTPHEADER, array("Content-Length: ".strlen($post))); 
curl_setopt ($c, CURLOPT_POSTFIELDS, $post);
curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($c, CURLOPT_CONNECTTIMEOUT , 0);
curl_setopt ($c, CURLOPT_TIMEOUT  , 20);
//Collect result
$pdf = curl_exec ($c);
$curlInfo = curl_getinfo($c);
curl_close($c);
Require answered 27/4, 2012 at 17:31 Comment(0)
A
3

This is a firewall issue, if you are using a VMware application, make sure the firewall on the antivirus is turned off or allowing connections.

If this server is on a secure network, please have a look at firewall rules of the server.

Thanks Ganesh PNS

Antiworld answered 13/10, 2015 at 5:30 Comment(0)
P
1

In my case there was problem in URL. I've use https://example.com - but they ensure 'www.' - so when i switched to https://www.example.com everything was ok. The proper header was sent 'Host: www.example.com'.

You can try make a request in firefox brwoser, persist it and copy as cURL - that how I've found it.

Pyrene answered 4/2, 2016 at 20:59 Comment(0)
I
1

We had the same issue, in making a websocket connection to the Load Balancer. The issue is in LB, accepting http connection on port 80 and forwarding the request to node (tomcat app on port 8080). We have changed this to accept tcp (http has been changed as 'tcp') connection on port 80. So the first handshake request is forwarded to Node and a websocket connection is made successfully on some random( as far as i know, may be wrong) port.

below command has been used to test the websocket handshake process.

curl -v -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: localhost" -H "Origin: http://LB URL:80" http://LB URL

  • Rebuilt URL to: http:LB URL/
  • Trying LB URL...
  • TCP_NODELAY set
  • Connected to LB URL (LB URL) port 80 (#0)

    GET / HTTP/1.1 Host: localhost User-Agent: curl/7.60.0 Accept: / Connection: Upgrade Upgrade: websocket Origin: http://LB URL:80

  • Recv failure: Connection reset by peer
  • Closing connection 0 curl: (56) Recv failure: Connection reset by peer
Intermigration answered 4/12, 2019 at 5:31 Comment(0)
A
1

This may be because that your TCP connections created by curl requests are not getting closed as soon as the job is done. This may lead to an increase in the number of worker_connections an Nginx process can hold and cause the nginx server to reset the new connections.

One way we can avoid the issue is by adding --retry and --retry-all-errors flags (available in the latest versions of curl) in your curl request so that your curl retries even in the case of connection reset by peer. Also increasing the number of worker_connections in nginx.conf file can also help you avoid reaching the max limit of TCP connections.

Try to close all the open TCP connections as soon as the job is done by the curl request.

Acrolith answered 19/7, 2023 at 7:5 Comment(0)
O
0

In my case, it was proxy settings in my local VM. The request was going to proxy which did not know about the server. By passing proxy solved the problem.

Oba answered 9/5, 2023 at 11:27 Comment(0)
L
0

I got the same error message "curl: (56) Recv failure: Connection was reset" when i tried these commands

curl http://google.com curl -L http://google.com

But it resolved when with HTTPS

curl https://google.com -----> 302 document moved message which is expected curl -L https://google.com

Laverty answered 14/7, 2023 at 15:54 Comment(0)
I
0

I my one of the application I suddenly stared getting following response.

56 Recv failure: Connection reset by peer

I was able to make the request to endpoint http://example.com/ws/soap?wsdl using curl.

curl -i http://example.com/ws/soap?wsdl

Also using the SoapUI I was able to get the response. But using the Php code to do a curl request I was getting 56 Recv failure: Connection reset by peer

I checked in the security software logs and in the WAF logs but found nothing.

I had a code like following

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $wsdl);
curl_setopt($curl, CURLOPT_VERBOSE, 0); 
curl_setopt($curl, CURLOPT_HTTPHEADER, $headerArr);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $requestXml);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);  
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,0); 
curl_setopt($curl, CURLOPT_TIMEOUT, 400);

$response = curl_exec($curl);
curl_close($curl);

Where I was passing the following header

$headerArr = array('Content-Type: text/xml;charset=UTF-8',
                    'SOAPAction: http://sap.com/xi/WebService/soap1.1',
                    'User-Agent: PHP-SOAP/5.2.9-2',
                    'Host: http://example.com/ws/soap?wsdl');
                

Due to some upgrade some setting had changed on the destination application side. After changing the Host from http://example.com/ws/soap?wsdl to example.com the issue got fixed.

$headerArr = array('Content-Type: text/xml;charset=UTF-8',
                    'SOAPAction: http://sap.com/xi/WebService/soap1.1',
                    'User-Agent: PHP-SOAP/5.2.9-2',
                    'Host: example.com');

So always try to edit the header also, if you are not able to find the root cause by other means.

Introspection answered 15/9, 2023 at 16:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.