diff --git a/codec/src/main/java/io/netty/handler/codec/DefaultHeaders.java b/codec/src/main/java/io/netty/handler/codec/DefaultHeaders.java
--- a/codec/src/main/java/io/netty/handler/codec/DefaultHeaders.java
+++ b/codec/src/main/java/io/netty/handler/codec/DefaultHeaders.java
@@ -1013,7 +1013,11 @@ protected void validateName(NameValidator<K> validator, boolean forAdd, K name)
     }
 
     protected void validateValue(ValueValidator<V> validator, K name, V value) {
-        validator.validate(value);
+        try {
+            validator.validate(value);
+        } catch (IllegalArgumentException e) {
+            throw new IllegalArgumentException("Validation failed for header '" + name + "'", e);
+        }
     }
 
     protected HeaderEntry<K, V> newHeaderEntry(int h, K name, V value, HeaderEntry<K, V> next) {

diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpHeadersTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpHeadersTest.java
--- a/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpHeadersTest.java
+++ b/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpHeadersTest.java
@@ -238,23 +238,25 @@ public void setObjectIterable() {
     @Test
     public void setCharSequenceValidatesValue() {
         final DefaultHttpHeaders headers = newDefaultDefaultHttpHeaders();
-        assertThrows(IllegalArgumentException.class, new Executable() {
+        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, new Executable() {
             @Override
             public void execute() throws Throwable {
                 headers.set(HEADER_NAME, ILLEGAL_VALUE);
             }
         });
+        assertTrue(exception.getMessage().contains(HEADER_NAME));
     }
 
     @Test
     public void setIterableValidatesValue() {
         final DefaultHttpHeaders headers = newDefaultDefaultHttpHeaders();
-        assertThrows(IllegalArgumentException.class, new Executable() {
+        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, new Executable() {
             @Override
             public void execute() throws Throwable {
                 headers.set(HEADER_NAME, Collections.singleton(ILLEGAL_VALUE));
             }
         });
+        assertTrue(exception.getMessage().contains(HEADER_NAME));
     }
 
     @Test

Display which header failed validation
### Expected behavior

Currently if a HeaderValue fails validation we get an IllegalArgumentException which has the message `a header value contains prohibited character {some_invalid_character} at index {index}`. Seeing this in production makes it hard to debug which header is having this problem.

### Actual behavior
We should instead have the message, `Header value for {header_name} contains prohibited character {some_invalid_character} at index {index}

To fix this I am suggesting to change the interface of ValueValidator to also take in the key which will be purely used for adding debug information.

org.io.netty.handler.codec.http.DefaultHttpHeadersTest