diff --git a/docs/content/2026-news.md b/docs/content/2026-news.md
index d4143521..184158a0 100644
--- a/docs/content/2026-news.md
+++ b/docs/content/2026-news.md
@@ -1,6 +1,36 @@
# Changelog - 2026
+## 25.3.0 - 2026-03-26
+
+### Bug Fixes
+
+- **HTTP/2 ASGI Body Duplication**: Fix request body being received twice in HTTP/2
+ ASGI requests, causing JSON parsing errors with "Extra data" messages
+ ([#3558](https://github.com/benoitc/gunicorn/issues/3558))
+
+- **ASGI Chunked EOF Handling**: Add `finish()` method to callback parser to handle
+ chunked encoding edge case where connection closes before final CRLF after zero-chunk
+
+### Security
+
+- **ASGI Parser Header Validation**: Add security checks per RFC 9110/9112:
+ - Reject duplicate Content-Length headers
+ - Reject requests with both Content-Length and Transfer-Encoding
+ - Reject chunked transfer encoding in HTTP/1.0
+ - Reject stacked chunked encoding
+ - Validate Transfer-Encoding values
+ - Strict chunk size validation
+
+### Changes
+
+- **Fast HTTP Parser**: Update to gunicorn_h1c >= 0.6.2 for `asgi_headers` property
+ which provides headers with lowercase names directly from the C parser
+
+- **ASGI PROXY Protocol**: Add PROXY protocol v1/v2 support to callback parser
+
+---
+
## 25.2.0 - 2026-03-24
### New Features
diff --git a/docs/content/news.md b/docs/content/news.md
index 5ac5b76e..6be3368d 100644
--- a/docs/content/news.md
+++ b/docs/content/news.md
@@ -1,6 +1,36 @@
# Changelog
+## 25.3.0 - 2026-03-26
+
+### Bug Fixes
+
+- **HTTP/2 ASGI Body Duplication**: Fix request body being received twice in HTTP/2
+ ASGI requests, causing JSON parsing errors with "Extra data" messages
+ ([#3558](https://github.com/benoitc/gunicorn/issues/3558))
+
+- **ASGI Chunked EOF Handling**: Add `finish()` method to callback parser to handle
+ chunked encoding edge case where connection closes before final CRLF after zero-chunk
+
+### Security
+
+- **ASGI Parser Header Validation**: Add security checks per RFC 9110/9112:
+ - Reject duplicate Content-Length headers
+ - Reject requests with both Content-Length and Transfer-Encoding
+ - Reject chunked transfer encoding in HTTP/1.0
+ - Reject stacked chunked encoding
+ - Validate Transfer-Encoding values
+ - Strict chunk size validation
+
+### Changes
+
+- **Fast HTTP Parser**: Update to gunicorn_h1c >= 0.6.2 for `asgi_headers` property
+ which provides headers with lowercase names directly from the C parser
+
+- **ASGI PROXY Protocol**: Add PROXY protocol v1/v2 support to callback parser
+
+---
+
## 25.2.0 - 2026-03-24
### New Features
diff --git a/gunicorn/__init__.py b/gunicorn/__init__.py
index 26a9e00a..6009fecc 100644
--- a/gunicorn/__init__.py
+++ b/gunicorn/__init__.py
@@ -2,7 +2,7 @@
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
-version_info = (25, 2, 0)
+version_info = (25, 3, 0)
__version__ = ".".join([str(v) for v in version_info])
SERVER = "gunicorn"
SERVER_SOFTWARE = "%s/%s" % (SERVER, __version__)
diff --git a/gunicorn/asgi/parser.py b/gunicorn/asgi/parser.py
index 818a71c6..a1f608a6 100644
--- a/gunicorn/asgi/parser.py
+++ b/gunicorn/asgi/parser.py
@@ -835,7 +835,9 @@ class CallbackRequest:
req.version = parser.http_version
# Headers - store both bytes (for ASGI scope) and strings (for compatibility)
- req.headers_bytes = list(parser.headers)
+ # Use asgi_headers (lowercase names) if available (fast parser >= 0.6.2),
+ # otherwise fall back to headers (Python parser already uses lowercase)
+ req.headers_bytes = list(getattr(parser, 'asgi_headers', None) or parser.headers)
req.headers = [
(n.decode('latin-1').upper(), v.decode('latin-1'))
for n, v in parser.headers
diff --git a/pyproject.toml b/pyproject.toml
index ba579434..07ae3e41 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -53,7 +53,11 @@ tornado = ["tornado>=6.5.0"]
gthread = []
setproctitle = ["setproctitle"]
http2 = ["h2>=4.1.0"]
-fast = ["gunicorn_h1c>=0.6.0"]
+
+
+
+fast = ["gunicorn_h1c>=0.6.2"]
+
testing = [
"gevent>=24.10.1",
"eventlet>=0.40.3",
diff --git a/requirements_test.txt b/requirements_test.txt
index 3093c4e6..4d26756a 100644
--- a/requirements_test.txt
+++ b/requirements_test.txt
@@ -3,4 +3,4 @@ coverage
pytest>=7.2.0
pytest-cov
pytest-asyncio
-gunicorn_h1c>=0.6.0
+gunicorn_h1c>=0.6.2
diff --git a/tests/conftest.py b/tests/conftest.py
index 018ffbc5..c3824279 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -21,7 +21,7 @@ def http_parser(request):
"""Parametrize tests over http_parser implementations."""
if request.param == "fast":
gunicorn_h1c = pytest.importorskip("gunicorn_h1c", reason="gunicorn_h1c required")
- # Require >= 0.6.0 for header framing validation
- if not hasattr(gunicorn_h1c, 'InvalidHeader'):
- pytest.skip("gunicorn_h1c >= 0.6.0 required")
+ # Require >= 0.6.2 for asgi_headers support
+ if not hasattr(gunicorn_h1c.H1CProtocol, 'asgi_headers'):
+ pytest.skip("gunicorn_h1c >= 0.6.2 required")
return request.param