diff --git a/build.yaml b/build.yaml
index a6feea507465fca4bb18a5892b08f19b61c60951..253a76448aa99e7555de51ee95f7f5bfba759a94 100644
--- a/build.yaml
+++ b/build.yaml
@@ -1185,6 +1185,7 @@ targets:
   - gpr
   corpus_dirs:
   - test/core/end2end/fuzzers/client_fuzzer_corpus
+  dict: test/core/end2end/fuzzers/hpack.dictionary
   maxlen: 2048
 - name: compression_test
   build: test
@@ -1674,6 +1675,7 @@ targets:
   - gpr
   corpus_dirs:
   - test/core/transport/chttp2/hpack_parser_corpus
+  dict: test/core/end2end/fuzzers/hpack.dictionary
   maxlen: 512
 - name: hpack_parser_test
   build: test
@@ -2025,6 +2027,7 @@ targets:
   - gpr
   corpus_dirs:
   - test/core/end2end/fuzzers/server_fuzzer_corpus
+  dict: test/core/end2end/fuzzers/hpack.dictionary
   maxlen: 2048
 - name: server_test
   build: test
diff --git a/templates/tools/fuzzer/runners.template b/templates/tools/fuzzer/runners.template
index 4b8d4f3c68fbf7acdb5932db9ab2cdb59d25c580..358d4315c277cf73112c57b8d8f1c613e74ae6fd 100644
--- a/templates/tools/fuzzer/runners.template
+++ b/templates/tools/fuzzer/runners.template
@@ -37,6 +37,10 @@ template: |
 
   flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=${selected.maxlen}"
   
+  %if selected.get('dict'):
+  flags="$flags -dict=${selected.dict}"
+  %endif
+
   if [ "$jobs" != "1" ]
   then
     flags="-jobs=$jobs -workers=$jobs $flags"
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
new file mode 100644
index 0000000000000000000000000000000000000000..185048600fc4489052a9811d51f45ed396215cd9
--- /dev/null
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -0,0 +1,91 @@
+# hpack fuzzing dictionary
+kw0="\x01""0"
+kw1="\x01""1"
+kw2="\x01""2"
+kw3="\x03""200"
+kw4="\x03""204"
+kw5="\x03""206"
+kw6="\x03""304"
+kw7="\x03""400"
+kw8="\x03""404"
+kw9="\x03""500"
+kw10="\x06""accept"
+kw11="\x0e""accept-charset"
+kw12="\x0f""accept-encoding"
+kw13="\x0f""accept-language"
+kw14="\x0d""accept-ranges"
+kw15="\x1b""access-control-allow-origin"
+kw16="\x03""age"
+kw17="\x05""allow"
+kw18="\x10""application/grpc"
+kw19="\x0a:authority"
+kw20="\x0d""authorization"
+kw21="\x0d""cache-control"
+kw22="\x0a""census-bin"
+kw23="\x11""census-binary-bin"
+kw24="\x13""content-disposition"
+kw25="\x10""content-encoding"
+kw26="\x10""content-language"
+kw27="\x0e""content-length"
+kw28="\x10""content-location"
+kw29="\x0d""content-range"
+kw30="\x0c""content-type"
+kw31="\x06""cookie"
+kw32="\x04""date"
+kw33="\x07""deflate"
+kw34="\x0c""deflate,gzip"
+kw35="\x00"
+kw36="\x04""etag"
+kw37="\x06""expect"
+kw38="\x07""expires"
+kw39="\x04""from"
+kw40="\x03GET"
+kw41="\x04grpc"
+kw42="\x14grpc-accept-encoding"
+kw43="\x0dgrpc-encoding"
+kw44="\x1egrpc-internal-encoding-request"
+kw45="\x0cgrpc-message"
+kw46="\x0bgrpc-status"
+kw47="\x0cgrpc-timeout"
+kw48="\x04gzip"
+kw49="\x0dgzip, deflate"
+kw50="\x04host"
+kw51="\x04http"
+kw52="\x05https"
+kw53="\x08identity"
+kw54="\x10identity,deflate"
+kw55="\x15identity,deflate,gzip"
+kw56="\x0didentity,gzip"
+kw57="\x08if-match"
+kw58="\x11if-modified-since"
+kw59="\x0dif-none-match"
+kw60="\x08if-range"
+kw61="\x13if-unmodified-since"
+kw62="\x0dlast-modified"
+kw63="\x04link"
+kw64="\x08location"
+kw65="\x0cmax-forwards"
+kw66="\x07:method"
+kw67="\x05:path"
+kw68="\x04POST"
+kw69="\x12proxy-authenticate"
+kw70="\x13proxy-authorization"
+kw71="\x03PUT"
+kw72="\x05range"
+kw73="\x07referer"
+kw74="\x07refresh"
+kw75="\x0bretry-after"
+kw76="\x07:scheme"
+kw77="\x06server"
+kw78="\x0aset-cookie"
+kw79="\x01/"
+kw80="\x0b/index.html"
+kw81="\x07:status"
+kw82="\x19strict-transport-security"
+kw83="\x02te"
+kw84="\x08trailers"
+kw85="\x11transfer-encoding"
+kw86="\x0auser-agent"
+kw87="\x04vary"
+kw88="\x03via"
+kw89="\x10www-authenticate"
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index b4ba02bbe58f06e1cedaab07e3489f057c831202..ad73a5e357bd684fa7c6c068247787d850fdd674 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -205,6 +205,7 @@ all_elems = sorted(list(all_elems), key=mangle)
 args = sys.argv[1:]
 H = None
 C = None
+D = None
 if args:
   if 'header' in args:
     H = sys.stdout
@@ -214,11 +215,17 @@ if args:
     C = sys.stdout
   else:
     C = open('/dev/null', 'w')
+  if 'dictionary' in args:
+    D = sys.stdout
+  else:
+    D = open('/dev/null', 'w')
 else:
   H = open(os.path.join(
       os.path.dirname(sys.argv[0]), '../../../src/core/lib/transport/static_metadata.h'), 'w')
   C = open(os.path.join(
       os.path.dirname(sys.argv[0]), '../../../src/core/lib/transport/static_metadata.c'), 'w')
+  D = open(os.path.join(
+      os.path.dirname(sys.argv[0]), '../../../test/core/end2end/fuzzers/hpack.dictionary'), 'w')
 
 # copy-paste copyright notice from this file
 with open(sys.argv[0]) as my_source:
@@ -235,6 +242,27 @@ with open(sys.argv[0]) as my_source:
     copyright.append(line)
   put_banner([H,C], [line[2:].rstrip() for line in copyright])
 
+
+hex_bytes = [ord(c) for c in "abcdefABCDEF0123456789"]
+
+
+def esc_c(line):
+  out = "\""
+  last_was_hex = False
+  for c in line:
+    if 32 <= c < 127:
+      if c in hex_bytes and last_was_hex:
+        out += "\"\""
+      if c != ord('"'):
+        out += chr(c)
+      else:
+        out += "\\\""
+      last_was_hex = False
+    else:
+      out += "\\x%02x" % c
+      last_was_hex = True
+  return out + "\""
+
 put_banner([H,C],
 """WARNING: Auto-generated code.
 
@@ -263,6 +291,10 @@ print >>H
 print >>C, 'grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];'
 print >>C
 
+print >>D, '# hpack fuzzing dictionary'
+for i, elem in enumerate(all_strs):
+  print >>D, 'kw%d=%s' % (i, esc_c([len(elem)] + [ord(c) for c in elem]))
+
 print >>H, '#define GRPC_STATIC_MDELEM_COUNT %d' % len(all_elems)
 print >>H, 'extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];'
 print >>H, 'extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];'
diff --git a/tools/fuzzer/runners/client_fuzzer.sh b/tools/fuzzer/runners/client_fuzzer.sh
index 97d4e60d90831a6597a2bd38a5856dc51d8c2624..39bdbc8d8ac096e2e8c334ae0ca99ac691480266 100644
--- a/tools/fuzzer/runners/client_fuzzer.sh
+++ b/tools/fuzzer/runners/client_fuzzer.sh
@@ -31,6 +31,8 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=2048"
 
+flags="$flags -dict=test/core/end2end/fuzzers/hpack.dictionary"
+
 if [ "$jobs" != "1" ]
 then
   flags="-jobs=$jobs -workers=$jobs $flags"
diff --git a/tools/fuzzer/runners/hpack_parser_fuzzer_test.sh b/tools/fuzzer/runners/hpack_parser_fuzzer_test.sh
index c6f70a623dcee9d3e2fcf99a6c4f89af9df29fa2..0cc468eeb7544f037458441a21f93ceba4e757ef 100644
--- a/tools/fuzzer/runners/hpack_parser_fuzzer_test.sh
+++ b/tools/fuzzer/runners/hpack_parser_fuzzer_test.sh
@@ -31,6 +31,8 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=512"
 
+flags="$flags -dict=test/core/end2end/fuzzers/hpack.dictionary"
+
 if [ "$jobs" != "1" ]
 then
   flags="-jobs=$jobs -workers=$jobs $flags"
diff --git a/tools/fuzzer/runners/http_fuzzer_test.sh b/tools/fuzzer/runners/http_fuzzer_test.sh
index bb54a238145618e917e58158208c5d1086662e48..a86d765509d559eeae8698ad4b4f55588725a30f 100644
--- a/tools/fuzzer/runners/http_fuzzer_test.sh
+++ b/tools/fuzzer/runners/http_fuzzer_test.sh
@@ -31,6 +31,7 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=2048"
 
+
 if [ "$jobs" != "1" ]
 then
   flags="-jobs=$jobs -workers=$jobs $flags"
diff --git a/tools/fuzzer/runners/json_fuzzer_test.sh b/tools/fuzzer/runners/json_fuzzer_test.sh
index e11e25dc097a51def12231be1b1488d78dcd1563..9d38ed8d55ca7e50cbbe02e745aa111d21010bd1 100644
--- a/tools/fuzzer/runners/json_fuzzer_test.sh
+++ b/tools/fuzzer/runners/json_fuzzer_test.sh
@@ -31,6 +31,7 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=512"
 
+
 if [ "$jobs" != "1" ]
 then
   flags="-jobs=$jobs -workers=$jobs $flags"
diff --git a/tools/fuzzer/runners/nanopb_fuzzer_response_test.sh b/tools/fuzzer/runners/nanopb_fuzzer_response_test.sh
index 97359277ce24dcd0cea1435d757c6a1375d4a5dd..b55d23b165ed2004626d683610c05870f8e3a988 100644
--- a/tools/fuzzer/runners/nanopb_fuzzer_response_test.sh
+++ b/tools/fuzzer/runners/nanopb_fuzzer_response_test.sh
@@ -31,6 +31,7 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=128"
 
+
 if [ "$jobs" != "1" ]
 then
   flags="-jobs=$jobs -workers=$jobs $flags"
diff --git a/tools/fuzzer/runners/nanopb_fuzzer_serverlist_test.sh b/tools/fuzzer/runners/nanopb_fuzzer_serverlist_test.sh
index 2dfaa2372fc8a99cd9018214d2779e76c2fb1571..a75aad6f3647945d2dc3c87f59ae78aab73919a1 100644
--- a/tools/fuzzer/runners/nanopb_fuzzer_serverlist_test.sh
+++ b/tools/fuzzer/runners/nanopb_fuzzer_serverlist_test.sh
@@ -31,6 +31,7 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=128"
 
+
 if [ "$jobs" != "1" ]
 then
   flags="-jobs=$jobs -workers=$jobs $flags"
diff --git a/tools/fuzzer/runners/server_fuzzer.sh b/tools/fuzzer/runners/server_fuzzer.sh
index fc0567f670b72919d9258e454c6de95f827c70b1..9d1d9dc17dccbb7d53821943801e189287caa69c 100644
--- a/tools/fuzzer/runners/server_fuzzer.sh
+++ b/tools/fuzzer/runners/server_fuzzer.sh
@@ -31,6 +31,8 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=2048"
 
+flags="$flags -dict=test/core/end2end/fuzzers/hpack.dictionary"
+
 if [ "$jobs" != "1" ]
 then
   flags="-jobs=$jobs -workers=$jobs $flags"
diff --git a/tools/fuzzer/runners/uri_fuzzer_test.sh b/tools/fuzzer/runners/uri_fuzzer_test.sh
index 5f33e734654473bfe81b9932d552ad06cb5e353d..8890a2b86a87e9e2c3e65b165faa8992109b097b 100644
--- a/tools/fuzzer/runners/uri_fuzzer_test.sh
+++ b/tools/fuzzer/runners/uri_fuzzer_test.sh
@@ -31,6 +31,7 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=128"
 
+
 if [ "$jobs" != "1" ]
 then
   flags="-jobs=$jobs -workers=$jobs $flags"