diff --git a/tornado/ioloop.py b/tornado/ioloop.py
index ad35787f..a1288e77 100644
--- a/tornado/ioloop.py
+++ b/tornado/ioloop.py
@@ -121,6 +121,16 @@ class IOLoop(Configurable):
     current instance. If ``make_current=False``, the new `IOLoop` will
     not try to become current.
 
+    In general, an `IOLoop` cannot survive a fork or be shared across
+    processes in any way. When multiple processes are being used, each
+    process should create its own `IOLoop`, which also implies that
+    any objects which depend on the `IOLoop` (such as
+    `.AsyncHTTPClient`) must also be created in the child processes.
+    As a guideline, anything that starts processes (including the
+    `tornado.process` and `multiprocessing` modules) should do so as
+    early as possible, ideally the first thing the application does
+    after loading its configuration in ``main()``.
+
     .. versionchanged:: 4.2
        Added the ``make_current`` keyword argument to the `IOLoop`
        constructor.
@@ -701,6 +711,7 @@ class PollIOLoop(IOLoop):
         self._stopped = False
         self._closing = False
         self._thread_ident = None
+        self._pid = os.getpid()
         self._blocking_signal_threshold = None
         self._timeout_counter = itertools.count()
 
@@ -753,6 +764,8 @@ class PollIOLoop(IOLoop):
     def start(self):
         if self._running:
             raise RuntimeError("IOLoop is already running")
+        if os.getpid() != self._pid:
+            raise RuntimeError("Cannot share PollIOLoops across processes")
         self._setup_logging()
         if self._stopped:
             self._stopped = False
diff --git a/tornado/web.py b/tornado/web.py
index 132f42dd..d79889fa 100644
--- a/tornado/web.py
+++ b/tornado/web.py
@@ -319,7 +319,10 @@ class RequestHandler(object):
         if reason is not None:
             self._reason = escape.native_str(reason)
         else:
-            self._reason = httputil.responses.get(status_code, "Unknown")
+            try:
+                self._reason = httputil.responses[status_code]
+            except KeyError:
+                raise ValueError("unknown status code %d" % status_code)
 
     def get_status(self):
         """Returns the status code for our response."""
@@ -1558,7 +1561,11 @@ class RequestHandler(object):
             # send a response.
             return
         if isinstance(e, HTTPError):
-            self.send_error(e.status_code, exc_info=sys.exc_info())
+            if e.status_code not in httputil.responses and not e.reason:
+                gen_log.error("Bad HTTP status code: %d", e.status_code)
+                self.send_error(500, exc_info=sys.exc_info())
+            else:
+                self.send_error(e.status_code, exc_info=sys.exc_info())
         else:
             self.send_error(500, exc_info=sys.exc_info())
 

Check _events and _handlers before start()
```
Traceback (most recent call last):
    File "/usr/local/lib/python2.7/site-packages/tornado/ioloop.py", line 887, in start
     fd_obj, handler_func = self._handlers[fd]
     KeyError: 16
```

https://github.com/tornadoweb/tornado/blob/master/tornado/ioloop.py#L883

I ran into this issue when testing using multiple processes and threads.  We sandbox our test processes using multiprocessing and were getting this cryptic error.

I found a blog post @toumorokoshi wrote going over his own experiences with this issue: http://y.tsutsumi.io/keyerror-in-self_handlers-a-journey-deep-into-tornados-internals.html

At the very least it would be nice to have some documentation suggesting that you run IOLoop.clear_instance() and IOLoop.clear_current() after a fork()
diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py
index de26c42e..d79ea52c 100644
--- a/tornado/test/web_test.py
+++ b/tornado/test/web_test.py
@@ -917,10 +917,6 @@ class ErrorResponseTest(WebTestCase):
             self.assertEqual(response.code, 503)
             self.assertTrue(b"503: Service Unavailable" in response.body)
 
-            response = self.fetch("/default?status=435")
-            self.assertEqual(response.code, 435)
-            self.assertTrue(b"435: Unknown" in response.body)
-
     def test_write_error(self):
         with ExpectLog(app_log, "Uncaught exception"):
             response = self.fetch("/write_error")
@@ -1493,9 +1489,9 @@ class StatusReasonTest(SimpleHandlerTestCase):
         response = self.fetch("/?code=682&reason=Bar")
         self.assertEqual(response.code, 682)
         self.assertEqual(response.reason, "Bar")
-        response = self.fetch("/?code=682")
-        self.assertEqual(response.code, 682)
-        self.assertEqual(response.reason, "Unknown")
+        with ExpectLog(app_log, 'Uncaught exception'):
+            response = self.fetch("/?code=682")
+        self.assertEqual(response.code, 500)
 
 
 @wsgi_safe

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio
apt-get update apt-get install -y gcc python3-dev
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
coverage==6.2
execnet==1.9.0
importlib-metadata==4.8.3
iniconfig==1.1.1
packaging==21.3
pluggy==1.0.0
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
pytest-asyncio==0.16.0
pytest-cov==4.0.0
pytest-mock==3.6.1
pytest-xdist==3.0.2
tomli==1.2.3
-e git+https://github.com/tornadoweb/tornado.git@06be57c11f98b24ce0f6ee2d04f0cfe8bfdb3b4d#egg=tornado
typing_extensions==4.1.1
zipp==3.6.0

name: tornado
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - coverage==6.2
      - execnet==1.9.0
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - packaging==21.3
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-asyncio==0.16.0
      - pytest-cov==4.0.0
      - pytest-mock==3.6.1
      - pytest-xdist==3.0.2
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - zipp==3.6.0
prefix: /opt/conda/envs/tornado

tornado/test/web_test.py::StatusReasonTest::test_status
tornado/test/web_test.py::SecureCookieV1Test::test_arbitrary_bytes tornado/test/web_test.py::SecureCookieV1Test::test_cookie_tampering_future_timestamp tornado/test/web_test.py::SecureCookieV1Test::test_round_trip tornado/test/web_test.py::SecureCookieV2Test::test_key_version_increment_version tornado/test/web_test.py::SecureCookieV2Test::test_key_version_invalidate_version tornado/test/web_test.py::SecureCookieV2Test::test_key_version_roundtrip tornado/test/web_test.py::SecureCookieV2Test::test_key_version_roundtrip_differing_version tornado/test/web_test.py::SecureCookieV2Test::test_round_trip tornado/test/web_test.py::CookieTest::test_cookie_special_char tornado/test/web_test.py::CookieTest::test_get_cookie tornado/test/web_test.py::CookieTest::test_set_cookie tornado/test/web_test.py::CookieTest::test_set_cookie_domain tornado/test/web_test.py::CookieTest::test_set_cookie_expires_days tornado/test/web_test.py::CookieTest::test_set_cookie_false_flags tornado/test/web_test.py::CookieTest::test_set_cookie_max_age tornado/test/web_test.py::CookieTest::test_set_cookie_overwrite tornado/test/web_test.py::AuthRedirectTest::test_absolute_auth_redirect tornado/test/web_test.py::AuthRedirectTest::test_relative_auth_redirect tornado/test/web_test.py::ConnectionCloseTest::test_connection_close tornado/test/web_test.py::RequestEncodingTest::test_error tornado/test/web_test.py::RequestEncodingTest::test_group_encoding tornado/test/web_test.py::RequestEncodingTest::test_group_question_mark tornado/test/web_test.py::RequestEncodingTest::test_slashes tornado/test/web_test.py::WSGISafeWebTest::test_decode_argument tornado/test/web_test.py::WSGISafeWebTest::test_decode_argument_invalid_unicode tornado/test/web_test.py::WSGISafeWebTest::test_decode_argument_plus tornado/test/web_test.py::WSGISafeWebTest::test_get_argument tornado/test/web_test.py::WSGISafeWebTest::test_get_body_arguments tornado/test/web_test.py::WSGISafeWebTest::test_get_query_arguments tornado/test/web_test.py::WSGISafeWebTest::test_header_injection tornado/test/web_test.py::WSGISafeWebTest::test_multi_header tornado/test/web_test.py::WSGISafeWebTest::test_no_gzip tornado/test/web_test.py::WSGISafeWebTest::test_optional_path tornado/test/web_test.py::WSGISafeWebTest::test_redirect tornado/test/web_test.py::WSGISafeWebTest::test_reverse_url tornado/test/web_test.py::WSGISafeWebTest::test_types tornado/test/web_test.py::WSGISafeWebTest::test_uimodule_resources tornado/test/web_test.py::WSGISafeWebTest::test_uimodule_unescaped tornado/test/web_test.py::WSGISafeWebTest::test_web_redirect tornado/test/web_test.py::WSGISafeWebTest::test_web_redirect_double_slash tornado/test/web_test.py::NonWSGIWebTests::test_empty_flush tornado/test/web_test.py::NonWSGIWebTests::test_flow_control tornado/test/web_test.py::ErrorResponseTest::test_default tornado/test/web_test.py::ErrorResponseTest::test_failed_write_error tornado/test/web_test.py::ErrorResponseTest::test_write_error tornado/test/web_test.py::StaticFileTest::test_absolute_static_url tornado/test/web_test.py::StaticFileTest::test_absolute_version_exclusion tornado/test/web_test.py::StaticFileTest::test_include_host_override tornado/test/web_test.py::StaticFileTest::test_path_traversal_protection tornado/test/web_test.py::StaticFileTest::test_relative_version_exclusion tornado/test/web_test.py::StaticFileTest::test_root_static_path tornado/test/web_test.py::StaticFileTest::test_static_304_if_modified_since tornado/test/web_test.py::StaticFileTest::test_static_304_if_none_match tornado/test/web_test.py::StaticFileTest::test_static_404 tornado/test/web_test.py::StaticFileTest::test_static_compressed_files tornado/test/web_test.py::StaticFileTest::test_static_etag tornado/test/web_test.py::StaticFileTest::test_static_files tornado/test/web_test.py::StaticFileTest::test_static_head tornado/test/web_test.py::StaticFileTest::test_static_head_range tornado/test/web_test.py::StaticFileTest::test_static_if_modified_since_pre_epoch tornado/test/web_test.py::StaticFileTest::test_static_if_modified_since_time_zone tornado/test/web_test.py::StaticFileTest::test_static_invalid_range tornado/test/web_test.py::StaticFileTest::test_static_range_if_none_match tornado/test/web_test.py::StaticFileTest::test_static_unsatisfiable_range_invalid_start tornado/test/web_test.py::StaticFileTest::test_static_unsatisfiable_range_zero_suffix tornado/test/web_test.py::StaticFileTest::test_static_url tornado/test/web_test.py::StaticFileTest::test_static_with_range tornado/test/web_test.py::StaticFileTest::test_static_with_range_end_edge tornado/test/web_test.py::StaticFileTest::test_static_with_range_full_file tornado/test/web_test.py::StaticFileTest::test_static_with_range_full_past_end tornado/test/web_test.py::StaticFileTest::test_static_with_range_neg_end tornado/test/web_test.py::StaticFileTest::test_static_with_range_partial_past_end tornado/test/web_test.py::StaticDefaultFilenameTest::test_static_default_filename tornado/test/web_test.py::StaticDefaultFilenameTest::test_static_default_redirect tornado/test/web_test.py::StaticFileWithPathTest::test_serve tornado/test/web_test.py::CustomStaticFileTest::test_serve tornado/test/web_test.py::CustomStaticFileTest::test_static_url tornado/test/web_test.py::HostMatchingTest::test_host_matching tornado/test/web_test.py::DefaultHostMatchingTest::test_default_host_matching tornado/test/web_test.py::NamedURLSpecGroupsTest::test_named_urlspec_groups tornado/test/web_test.py::ClearHeaderTest::test_clear_header tornado/test/web_test.py::Header204Test::test_204_headers tornado/test/web_test.py::Header304Test::test_304_headers tornado/test/web_test.py::DateHeaderTest::test_date_header tornado/test/web_test.py::RaiseWithReasonTest::test_httperror_str tornado/test/web_test.py::RaiseWithReasonTest::test_httperror_str_from_httputil tornado/test/web_test.py::RaiseWithReasonTest::test_raise_with_reason tornado/test/web_test.py::ErrorHandlerXSRFTest::test_404_xsrf tornado/test/web_test.py::ErrorHandlerXSRFTest::test_error_xsrf tornado/test/web_test.py::GzipTestCase::test_gzip tornado/test/web_test.py::GzipTestCase::test_gzip_not_requested tornado/test/web_test.py::GzipTestCase::test_gzip_static tornado/test/web_test.py::GzipTestCase::test_vary_already_present tornado/test/web_test.py::GzipTestCase::test_vary_already_present_multiple tornado/test/web_test.py::PathArgsInPrepareTest::test_kw tornado/test/web_test.py::PathArgsInPrepareTest::test_pos tornado/test/web_test.py::ClearAllCookiesTest::test_clear_all_cookies tornado/test/web_test.py::ExceptionHandlerTest::test_http_error tornado/test/web_test.py::ExceptionHandlerTest::test_known_error tornado/test/web_test.py::ExceptionHandlerTest::test_unknown_error tornado/test/web_test.py::BuggyLoggingTest::test_buggy_log_exception tornado/test/web_test.py::UIMethodUIModuleTest::test_ui_method tornado/test/web_test.py::GetArgumentErrorTest::test_catch_error tornado/test/web_test.py::MultipleExceptionTest::test_multi_exception tornado/test/web_test.py::SetLazyPropertiesTest::test_set_properties tornado/test/web_test.py::GetCurrentUserTest::test_get_current_user_from_ui_module_is_lazy tornado/test/web_test.py::GetCurrentUserTest::test_get_current_user_from_ui_module_works tornado/test/web_test.py::GetCurrentUserTest::test_get_current_user_works tornado/test/web_test.py::UnimplementedHTTPMethodsTest::test_unimplemented_standard_methods tornado/test/web_test.py::UnimplementedNonStandardMethodsTest::test_unimplemented_other tornado/test/web_test.py::UnimplementedNonStandardMethodsTest::test_unimplemented_patch tornado/test/web_test.py::AllHTTPMethodsTest::test_standard_methods tornado/test/web_test.py::PatchMethodTest::test_other tornado/test/web_test.py::PatchMethodTest::test_patch tornado/test/web_test.py::FinishInPrepareTest::test_finish_in_prepare tornado/test/web_test.py::Default404Test::test_404 tornado/test/web_test.py::Custom404Test::test_404 tornado/test/web_test.py::DefaultHandlerArgumentsTest::test_403 tornado/test/web_test.py::HandlerByNameTest::test_handler_by_name tornado/test/web_test.py::StreamingRequestBodyTest::test_close_during_upload tornado/test/web_test.py::StreamingRequestBodyTest::test_early_return tornado/test/web_test.py::StreamingRequestBodyTest::test_early_return_with_data tornado/test/web_test.py::StreamingRequestBodyTest::test_streaming_body tornado/test/web_test.py::DecoratedStreamingRequestFlowControlTest::test_flow_control_chunked_body tornado/test/web_test.py::DecoratedStreamingRequestFlowControlTest::test_flow_control_compressed_body tornado/test/web_test.py::DecoratedStreamingRequestFlowControlTest::test_flow_control_fixed_body tornado/test/web_test.py::NativeStreamingRequestFlowControlTest::test_flow_control_chunked_body tornado/test/web_test.py::NativeStreamingRequestFlowControlTest::test_flow_control_compressed_body tornado/test/web_test.py::NativeStreamingRequestFlowControlTest::test_flow_control_fixed_body tornado/test/web_test.py::IncorrectContentLengthTest::test_content_length_too_high tornado/test/web_test.py::IncorrectContentLengthTest::test_content_length_too_low tornado/test/web_test.py::ClientCloseTest::test_client_close tornado/test/web_test.py::SignedValueTest::test_expired tornado/test/web_test.py::SignedValueTest::test_key_version_retrieval tornado/test/web_test.py::SignedValueTest::test_key_versioning_invalid_key tornado/test/web_test.py::SignedValueTest::test_key_versioning_read_write_default_key tornado/test/web_test.py::SignedValueTest::test_key_versioning_read_write_non_default_key tornado/test/web_test.py::SignedValueTest::test_known_values tornado/test/web_test.py::SignedValueTest::test_name_swap tornado/test/web_test.py::SignedValueTest::test_non_ascii tornado/test/web_test.py::SignedValueTest::test_payload_tampering tornado/test/web_test.py::SignedValueTest::test_signature_tampering tornado/test/web_test.py::XSRFTest::test_cross_user tornado/test/web_test.py::XSRFTest::test_distinct_tokens tornado/test/web_test.py::XSRFTest::test_refresh_token tornado/test/web_test.py::XSRFTest::test_versioning tornado/test/web_test.py::XSRFTest::test_xsrf_fail_argument_invalid_format tornado/test/web_test.py::XSRFTest::test_xsrf_fail_body_no_cookie tornado/test/web_test.py::XSRFTest::test_xsrf_fail_cookie_invalid_format tornado/test/web_test.py::XSRFTest::test_xsrf_fail_cookie_no_body tornado/test/web_test.py::XSRFTest::test_xsrf_fail_no_token tornado/test/web_test.py::XSRFTest::test_xsrf_success_header tornado/test/web_test.py::XSRFTest::test_xsrf_success_non_hex_token tornado/test/web_test.py::XSRFTest::test_xsrf_success_post_body tornado/test/web_test.py::XSRFTest::test_xsrf_success_query_string tornado/test/web_test.py::XSRFTest::test_xsrf_success_short_token tornado/test/web_test.py::XSRFCookieKwargsTest::test_xsrf_httponly tornado/test/web_test.py::FinishExceptionTest::test_finish_exception tornado/test/web_test.py::DecoratorTest::test_addslash tornado/test/web_test.py::DecoratorTest::test_removeslash tornado/test/web_test.py::CacheTest::test_multiple_strong_etag_match tornado/test/web_test.py::CacheTest::test_multiple_strong_etag_not_match tornado/test/web_test.py::CacheTest::test_multiple_weak_etag_match tornado/test/web_test.py::CacheTest::test_multiple_weak_etag_not_match tornado/test/web_test.py::CacheTest::test_strong_etag_match tornado/test/web_test.py::CacheTest::test_strong_etag_not_match tornado/test/web_test.py::CacheTest::test_weak_etag_match tornado/test/web_test.py::CacheTest::test_weak_etag_not_match tornado/test/web_test.py::CacheTest::test_wildcard_etag tornado/test/web_test.py::RequestSummaryTest::test_missing_remote_ip tornado/test/web_test.py::HTTPErrorTest::test_copy tornado/test/web_test.py::ApplicationTest::test_listen tornado/test/web_test.py::URLSpecReverseTest::test_non_reversible tornado/test/web_test.py::URLSpecReverseTest::test_reverse tornado/test/web_test.py::URLSpecReverseTest::test_reverse_arguments tornado/test/web_test.py::RedirectHandlerTest::test_basic_redirect tornado/test/web_test.py::RedirectHandlerTest::test_redirect_pattern
tornado/web.py tornado/ioloop.py
tornado/web.py tornado/ioloop.py