title: Receiving GET 400 when trying to implement socket.io communication. Node.js, ELB, Route 53, CloudFront, and s3
body: <p>Note** I was able to get things operational by taking cloudfront out of the picture for the server.com domain by just using route-53 and the elastic beanstalk environment. Still would be great to know why cloudfront was blocking this, but not an immediate concern for development **</p>
  <p>I am serving a node.js static socket.io client form an s3 bucket using cloudfront and route 53. I am attempting to get this client to talk to a node.js web server using elastic beanstalk. The webserver is connected with amazon certificate manager generated ssl using a route 53 domain and cloudfront.</p>
  <p>using an http client and directly connecting to the beanstalk environment I am seeing desired functionality. However, when I try to move to SSL/https with the client and server I am receiving:</p>
  <pre><code>(log from /var/log/nginx/error.log on elastic beanstalk instance)
  
  &quot;GET /socket.io/ HTTP/1.1&quot; 400 51 &quot;-&quot; &quot;Amazon CloudFront&quot;
  </code></pre>
  <p>here is the client code that is running from the static s3 https domain:</p>
  <pre><code>import ioClient from &quot;socket.io-client&quot;;
  
  const ENDPOINT = &quot;https://server.com&quot;;
  export const socket = ioClient(ENDPOINT);
  </code></pre>
  <p>here is the server side. process.env.port is set to 8080, and I can verify the app is listening on 8080 through elastic beanstalk logs.</p>
  <pre><code>const express = require(&quot;express&quot;);
  const http = require(&quot;http&quot;);
  const socket_io = require(&quot;socket.io&quot;);
  
  const index = require(&quot;./routes/index&quot;);
  const app = express();
  app.use(index);
  
  const server = http.createServer(app);
  const io = socket_io(server);
  
  const port = process.env.port || 4001;
  server.listen(port, () =&gt; console.log(`http server listing on port ${port}`));
  </code></pre>
  <p>Inside the ALB I have an https listener set up on port 443 with Amazon Certificate Manager (ACM) ssl certification. The listener has a process that maps the 443 https to 8080 on http, from where I think ngnix should be acting as a reverse proxy to my socket.io listener on 8080</p>
  <p>Listeners &amp; Processors</p>
  <p><a href="https://i.stack.imgur.com/ynAi4.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ynAi4.png" alt="443 being forwarded to 8080" /></a></p>
  <p><a href="https://i.stack.imgur.com/hbXmr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/hbXmr.png" alt="https ACM SSL" /></a></p>
  <p>In the root of my node project folder I have a .ebextensions directory and inside that a file named 01_files.config with these contents:</p>
  <pre><code>files:
      &quot;/etc/nginx/conf.d/websocketupgrade.conf&quot; :
          mode: &quot;000755&quot;
          owner: root
          group: root
          content: |
               proxy_pass http://localhost:8080;
               proxy_set_header Upgrade $http_upgrade;
               proxy_set_header Connection &quot;upgrade&quot;;
               proxy_http_version 1.1;
               proxy_set_header Host $host;
  </code></pre>
  <p>From the comments in this post : <a href="https://stackoverflow.com/questions/23987640/socket-io-handshake-return-error-transport-unknown">socket.io handshake return error &quot;Transport unknown&quot;</a> I found the following socket.io error codes</p>
  <pre><code>engine.io message type:
  
  open =0
  close =1
  ping =2
  pong =3
  message =4
  upgrade =5
  noop =6
  socket.io message type:
  
  connect = 0
  disconnect = 1
  event = 2
  ack = 3
  error = 4
  binary_event = 5
  binary_ack = 6
  </code></pre>
  <p>so, 400 51 could possibly mean &quot;Bad request, upgrade-disconnect.&quot;</p>
  <p>Here is the response body :
  <code>{&quot;code&quot;:0,&quot;message&quot;:&quot;Transport unknown&quot;}</code></p>
  <p>And here is the error on the client app in browser:</p>
  <p><code>polling-xhr.js:268 GET https://server.com/socket.io/?EIO=3&amp;transport=polling&amp;t=NIgQkyr 400</code></p>
  <p>which looks like a failed polling request on the xhr transport layer</p>