diff --git a/falcon/request.py b/falcon/request.py
index 0663c21..be8aabf 100644
--- a/falcon/request.py
+++ b/falcon/request.py
@@ -343,6 +343,9 @@ class Request(object):
             value = self.env['HTTP_RANGE']
             if value.startswith('bytes='):
                 value = value[6:]
+            else:
+                msg = "The value must be prefixed with 'bytes='"
+                raise HTTPInvalidHeader(msg, 'Range')
         except KeyError:
             return None
 

Make "bytes" prefix in Range header value required
Currently, range header values without a "bytes" prefix are allowed. Change the code to always require a "bytes" prefix.
diff --git a/tests/test_req_vars.py b/tests/test_req_vars.py
index 904d622..5ee1809 100644
--- a/tests/test_req_vars.py
+++ b/tests/test_req_vars.py
@@ -368,15 +368,15 @@ class TestReqVars(testing.TestBase):
         self.assertEqual(preferred_type, None)
 
     def test_range(self):
-        headers = {'Range': '10-'}
+        headers = {'Range': 'bytes=10-'}
         req = Request(testing.create_environ(headers=headers))
         self.assertEqual(req.range, (10, -1))
 
-        headers = {'Range': '10-20'}
+        headers = {'Range': 'bytes=10-20'}
         req = Request(testing.create_environ(headers=headers))
         self.assertEqual(req.range, (10, 20))
 
-        headers = {'Range': '-10240'}
+        headers = {'Range': 'bytes=-10240'}
         req = Request(testing.create_environ(headers=headers))
         self.assertEqual(req.range, (-10240, -1))
 
@@ -392,62 +392,62 @@ class TestReqVars(testing.TestBase):
         self.assertIs(req.range, None)
 
     def test_range_invalid(self):
-        headers = {'Range': '10240'}
+        headers = {'Range': 'bytes=10240'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': '-'}
+        headers = {'Range': 'bytes=-'}
         expected_desc = ('The value provided for the Range header is '
                          'invalid. The byte offsets are missing.')
         self._test_error_details(headers, 'range',
                                  falcon.HTTPInvalidHeader,
                                  'Invalid header value', expected_desc)
 
-        headers = {'Range': '--'}
+        headers = {'Range': 'bytes=--'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': '-3-'}
+        headers = {'Range': 'bytes=-3-'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': '-3-4'}
+        headers = {'Range': 'bytes=-3-4'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': '3-3-4'}
+        headers = {'Range': 'bytes=3-3-4'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': '3-3-'}
+        headers = {'Range': 'bytes=3-3-'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': '3-3- '}
+        headers = {'Range': 'bytes=3-3- '}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': 'fizbit'}
+        headers = {'Range': 'bytes=fizbit'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': 'a-'}
+        headers = {'Range': 'bytes=a-'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': 'a-3'}
+        headers = {'Range': 'bytes=a-3'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': '-b'}
+        headers = {'Range': 'bytes=-b'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': '3-b'}
+        headers = {'Range': 'bytes=3-b'}
         req = Request(testing.create_environ(headers=headers))
         self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)
 
-        headers = {'Range': 'x-y'}
+        headers = {'Range': 'bytes=x-y'}
         expected_desc = ('The value provided for the Range header is '
                          'invalid. It must be a byte range formatted '
                          'according to RFC 2616.')
@@ -463,6 +463,14 @@ class TestReqVars(testing.TestBase):
                                  falcon.HTTPInvalidHeader,
                                  'Invalid header value', expected_desc)
 
+        headers = {'Range': '10-'}
+        expected_desc = ("The value provided for the Range "
+                         "header is invalid. The value must be "
+                         "prefixed with 'bytes='")
+        self._test_error_details(headers, 'range',
+                                 falcon.HTTPInvalidHeader,
+                                 'Invalid header value', expected_desc)
+
     def test_missing_attribute_header(self):
         req = Request(testing.create_environ())
         self.assertEqual(req.range, None)

pip install -e .
parse_log_pytest
requirements.txt
nose coverage ddt pyyaml requests six testtools pytest
apt-get update apt-get install -y gcc
3.9
tools/test-requires
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi==2025.1.31
charset-normalizer==3.4.1
coverage==7.8.0
ddt==1.7.2
exceptiongroup==1.2.2
-e git+https://github.com/falconry/falcon.git@9dc3d87259b8fc50abc638a42b20e1eaa04d0cbc#egg=falcon
idna==3.10
iniconfig==2.1.0
nose==1.3.7
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
python-mimeparse==2.0.0
PyYAML==6.0.2
requests==2.32.3
six==1.17.0
testtools==2.7.2
tomli==2.2.1
urllib3==2.3.0

name: falcon
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
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - 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=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - coverage==7.8.0
      - ddt==1.7.2
      - exceptiongroup==1.2.2
      - idna==3.10
      - iniconfig==2.1.0
      - nose==1.3.7
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - python-mimeparse==2.0.0
      - pyyaml==6.0.2
      - requests==2.32.3
      - six==1.17.0
      - testtools==2.7.2
      - tomli==2.2.1
      - urllib3==2.3.0
prefix: /opt/conda/envs/falcon

tests/test_req_vars.py::TestReqVars::test_range_invalid
tests/test_req_vars.py::TestReqVars::test_client_accepts
tests/test_req_vars.py::TestReqVars::test_attribute_headers tests/test_req_vars.py::TestReqVars::test_bogus_content_length_nan tests/test_req_vars.py::TestReqVars::test_bogus_content_length_neg tests/test_req_vars.py::TestReqVars::test_client_accepts_bogus tests/test_req_vars.py::TestReqVars::test_client_accepts_props tests/test_req_vars.py::TestReqVars::test_client_prefers tests/test_req_vars.py::TestReqVars::test_content_length tests/test_req_vars.py::TestReqVars::test_content_length_method tests/test_req_vars.py::TestReqVars::test_content_type_method tests/test_req_vars.py::TestReqVars::test_date tests/test_req_vars.py::TestReqVars::test_date_invalid_1_Thu__04_Apr_2013 tests/test_req_vars.py::TestReqVars::test_date_invalid_2_ tests/test_req_vars.py::TestReqVars::test_date_missing tests/test_req_vars.py::TestReqVars::test_empty tests/test_req_vars.py::TestReqVars::test_empty_path tests/test_req_vars.py::TestReqVars::test_host tests/test_req_vars.py::TestReqVars::test_method tests/test_req_vars.py::TestReqVars::test_missing_attribute_header tests/test_req_vars.py::TestReqVars::test_missing_qs tests/test_req_vars.py::TestReqVars::test_range tests/test_req_vars.py::TestReqVars::test_reconstruct_url tests/test_req_vars.py::TestReqVars::test_relative_uri tests/test_req_vars.py::TestReqVars::test_subdomain tests/test_req_vars.py::TestReqVars::test_uri tests/test_req_vars.py::TestReqVars::test_uri_http_1_0 tests/test_req_vars.py::TestReqVars::test_uri_https
falcon/request.py
falcon/request.py