Doing as described in title can result in websocket dirty close connection, to prevent this can do setTimeout(() => ws.send('msg'), 0) if need to send message in Open handler after async Upgrade. I think calling res.upgrade() while corked calls the Open handler still corked and ws.send inside the upgrade cork can cause some tcp or protocol error. Removing res.cork() fixes connection error but displays warnings that cork is missing