diff --git a/IPython/frontend/html/notebook/notebookapp.py b/IPython/frontend/html/notebook/notebookapp.py
index 35a04485c..86d48fd41 100644
--- a/IPython/frontend/html/notebook/notebookapp.py
+++ b/IPython/frontend/html/notebook/notebookapp.py
@@ -40,6 +40,7 @@ from jinja2 import Environment, FileSystemLoader
from zmq.eventloop import ioloop
ioloop.install()
+import tornado
from tornado import httpserver
from tornado import web
@@ -522,6 +523,30 @@ class NotebookApp(BaseIPythonApplication):
try:
self.http_server.listen(port, self.ip)
except socket.error as e:
+ # XXX: remove the e.errno == -9 block when we require
+ # tornado >= 3.0
+ if e.errno == -9 and tornado.version_info[0] < 3:
+ # The flags passed to socket.getaddrinfo from
+ # tornado.netutils.bind_sockets can cause "gaierror:
+ # [Errno -9] Address family for hostname not supported"
+ # when the interface is not associated, for example.
+ # Changing the flags to exclude socket.AI_ADDRCONFIG does
+ # not cause this error, but the only way to do this is to
+ # monkeypatch socket to remove the AI_ADDRCONFIG attribute
+ saved_AI_ADDRCONFIG = socket.AI_ADDRCONFIG
+ self.log.warn('Monkeypatching socket to fix tornado bug')
+ del(socket.AI_ADDRCONFIG)
+ try:
+ # retry the tornado call without AI_ADDRCONFIG flags
+ self.http_server.listen(port, self.ip)
+ except socket.error as e2:
+ e = e2
+ else:
+ self.port = port
+ success = True
+ break
+ # restore the monekypatch
+ socket.AI_ADDRCONFIG = saved_AI_ADDRCONFIG
if e.errno != errno.EADDRINUSE:
raise
self.log.info('The port %i is already in use, trying another random port.' % port)