Socket.io: Can't set headers after they're sent

Created on 3 Nov 2017  路  5Comments  路  Source: socketio/socket.io

Note: for support questions, please use one of these channels: stackoverflow or slack

You want to:

  • [x] report a bug
  • [ ] request a feature

Current behaviour

I am trying to make an app with Node.js, Express and Socket.io. I'm using EJS as the view engine. This is the relevant part of my code -

const express = require('express');
const app = express();
//copied from socket.io tutorial 
const http = require('http').Server(app);
const io = require('socket.io')(http);
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, '../templates'));
...
app.get('/', function (req, res) {
    logger.info('index');
    return res.render('index');
});
...
const port = process.env.PORT || localConfig.port;
http.listen(port);

Now if I navigate to localhost:3000, I get the error

Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:489:11)
at ServerResponse.setHeader (_http_outgoing.js:496:3)
at ServerResponse.header (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/response.js:767:10)
at ServerResponse.contentType (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/response.js:595:15)
at ServerResponse.send (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/response.js:145:14)
at done (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/response.js:1004:10)
at tryHandleCache (/home/aniket/Documents/HumbleHelper/node_modules/ejs/lib/ejs.js:228:10)
at View.exports.renderFile [as engine] (/home/aniket/Documents/HumbleHelper/node_modules/ejs/lib/ejs.js:437:10)
at View.render (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/view.js:135:8)
at tryRender (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/application.js:640:10)

From the log, I can see that 'index' has been called twice, followed by the error. However, if I remove this line -
const io = require('socket.io')(http);

Steps to reproduce (if the current behaviour is a bug)

Navigate the browser to localhost:3000 and it fails. I have tried a res.send() instead of res.render() but that fails too.

Expected behaviour

The index page should be rendered correctly

Setup

  • OS: Arch Linux
  • browser: Google Chrome 59
  • socket.io version: 2.0.4

Other information (e.g. stacktraces, related issues, suggestions how to fix)

I'm also using Passport, Helmet, Body-parser and express-session in conjunction with Socket.io

Most helpful comment

This happens if I share the same port between Socket.io and Express

All 5 comments

This happens if I share the same port between Socket.io and Express

I tried giving Socket.io another port. And tried to connect to that port. Now it gives this error

Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:489:11)
    at ServerResponse.setHeader (_http_outgoing.js:496:3)
    at expressInit (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/middleware/init.js:30:42)
    at Layer.handle [as handle_request] (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:317:13)
    at /home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:335:12)
    at next (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:275:10)
    at query (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/middleware/query.js:45:5)
    at Layer.handle [as handle_request] (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/layer.js:95:5)
Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:489:11)
    at ServerResponse.setHeader (_http_outgoing.js:496:3)
    at expressInit (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/middleware/init.js:30:42)
    at Layer.handle [as handle_request] (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:317:13)
    at /home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:335:12)
    at next (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:275:10)
    at query (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/middleware/query.js:45:5)
    at Layer.handle [as handle_request] (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/layer.js:95:5)
Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:489:11)
    at ServerResponse.setHeader (_http_outgoing.js:496:3)
    at expressInit (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/middleware/init.js:30:42)
    at Layer.handle [as handle_request] (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:317:13)
    at /home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:335:12)
    at next (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/index.js:275:10)
    at query (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/middleware/query.js:45:5)
    at Layer.handle [as handle_request] (/home/aniket/Documents/HumbleHelper/node_modules/express/lib/router/layer.js:95:5)
_http_outgoing.js:489
    throw new Error('Can\'t set headers after they are sent.');
    ^

Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:489:11)
    at ServerResponse.setHeader (_http_outgoing.js:496:3)
    at ServerResponse.writeHead (_http_server.js:209:21)
    at IncomingMessage.onEnd (/home/aniket/Documents/HumbleHelper/node_modules/engine.io/lib/transports/polling.js:180:9)
    at emitNone (events.js:105:13)
    at IncomingMessage.emit (events.js:207:7)
    at endReadableNT (_stream_readable.js:1059:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)

I have found the issue at

require('appmetrics-dash').attach();
require('appmetrics-prometheus').attach();

Working Fiddle:
https://github.com/BrokenMutant/socket.io-fiddle
run "npm start" and go to localhost:3000 and the console should show the error

Hi @Herald-Of-Solace, I know this is 2 years old but fyi I believe the problem is not with socket.io, but with the appmetrics packages.

appmetrics-dash.attach() is not designed to be followed by another attach call (e.g. appmetrics-dash.attach() or appmetrics-prometheus.attach()).

In your fiddle you should do:

const express = require('express');
const app = express();
const port = 3000;
app.set('view engine','ejs');
app.set('views',__dirname + '/public');
app.get('/',(req,res) => 
    res.render('index'));

app.use('/metrics', require('appmetrics-prometheus').endpoint()); // see https://github.com/CloudNativeJS/appmetrics-prometheus#usage

var server = app.listen(port);

require('appmetrics-dash').monitor({server, app}); // see https://github.com/appsody/stacks/blob/b6333dceb86a2501bfa987a5ad91964cf2cad104/incubator/nodejs-express/image/project/server.js#L13

const io = require('socket.io')(server);
io.on('connect', onConnect);
server.listen(port, () => console.log('server listening on port ' + port));

function onConnect(socket){
  console.log('connect ' + socket.id);

  socket.on('disconnect', () => console.log('disconnect ' + socket.id));
}

Thanks @rwalle61 for your help! As far as I remember I was following the default Node JS template for IBM Bluemix (It was for a hackathon), and the lines were already there if memory serves!
Anyway, I completed the hackathon by removing those lines. Now I see why this happened! Thanks for your help!

Was this page helpful?
0 / 5 - 0 ratings