Additional responses can be status groups or "default"
diff --git a/fastapi/openapi/utils.py b/fastapi/openapi/utils.py
index 9c043103dc0b7..96be89d937fe0 100644
--- a/fastapi/openapi/utils.py
+++ b/fastapi/openapi/utils.py
@@ -43,6 +43,15 @@
     },
 }
 
+status_code_ranges: Dict[str, str] = {
+    "1XX": "Information",
+    "2XX": "Success",
+    "3XX": "Redirection",
+    "4XX": "Client Error",
+    "5XX": "Server Error",
+    "default": "Default Response",
+}
+
 
 def get_openapi_params(dependant: Dependant) -> List[Field]:
     flat_dependant = get_flat_dependant(dependant)
@@ -190,12 +199,14 @@ def get_openapi_path(
                         response.setdefault("content", {}).setdefault(
                             "application/json", {}
                         )["schema"] = response_schema
-                    status_text = http.client.responses.get(int(additional_status_code))
+                    status_text: Optional[str] = status_code_ranges.get(
+                        str(additional_status_code).upper()
+                    ) or http.client.responses.get(int(additional_status_code))
                     response.setdefault(
                         "description", status_text or "Additional Response"
                     )
                     operation.setdefault("responses", {})[
-                        str(additional_status_code)
+                        str(additional_status_code).upper()
                     ] = response
             status_code = str(route.status_code)
             response_schema = {"type": "string"}
diff --git a/tests/test_additional_responses_bad.py b/tests/test_additional_responses_bad.py
new file mode 100644
index 0000000000000..fda4755763b3e
--- /dev/null
+++ b/tests/test_additional_responses_bad.py
@@ -0,0 +1,40 @@
+import pytest
+from fastapi import FastAPI
+from starlette.testclient import TestClient
+
+app = FastAPI()
+
+
+@app.get("/a", responses={"hello": {"description": "Not a valid additional response"}})
+async def a():
+    pass  # pragma: no cover
+
+
+openapi_schema = {
+    "openapi": "3.0.2",
+    "info": {"title": "Fast API", "version": "0.1.0"},
+    "paths": {
+        "/a": {
+            "get": {
+                "responses": {
+                    # this is how one would imagine the openapi schema to be
+                    # but since the key is not valid, openapi.utils.get_openapi will raise ValueError
+                    "hello": {"description": "Not a valid additional response"},
+                    "200": {
+                        "description": "Successful Response",
+                        "content": {"application/json": {"schema": {}}},
+                    },
+                },
+                "summary": "A",
+                "operationId": "a_a_get",
+            }
+        }
+    },
+}
+
+client = TestClient(app)
+
+
+def test_openapi_schema():
+    with pytest.raises(ValueError):
+        client.get("/openapi.json")
diff --git a/tests/test_additional_responses_router.py b/tests/test_additional_responses_router.py
index 49ef5f04992f4..ce66ead7e0c71 100644
--- a/tests/test_additional_responses_router.py
+++ b/tests/test_additional_responses_router.py
@@ -10,12 +10,24 @@ async def a():
     return "a"
 
 
-@router.get("/b", responses={502: {"description": "Error 2"}})
+@router.get(
+    "/b",
+    responses={
+        502: {"description": "Error 2"},
+        "4XX": {"description": "Error with range, upper"},
+    },
+)
 async def b():
     return "b"
 
 
-@router.get("/c", responses={501: {"description": "Error 3"}})
+@router.get(
+    "/c",
+    responses={
+        "400": {"description": "Error with str"},
+        "5xx": {"description": "Error with range, lower"},
+    },
+)
 async def c():
     return "c"
 
@@ -43,6 +55,7 @@ async def c():
             "get": {
                 "responses": {
                     "502": {"description": "Error 2"},
+                    "4XX": {"description": "Error with range, upper"},
                     "200": {
                         "description": "Successful Response",
                         "content": {"application/json": {"schema": {}}},
@@ -55,7 +68,8 @@ async def c():
         "/c": {
             "get": {
                 "responses": {
-                    "501": {"description": "Error 3"},
+                    "400": {"description": "Error with str"},
+                    "5XX": {"description": "Error with range, lower"},
                     "200": {
                         "description": "Successful Response",
                         "content": {"application/json": {"schema": {}}},

Catching exception when generating OpenAPI specification. Added status groups and "default" as possible key for the additional responses.

If merged, this issue fixes #428 