diff --git a/caddyhttp/proxy/setup_test.go b/caddyhttp/proxy/setup_test.go
index 7dff3bbc83fee1c22915011021eb69a3fa3cdb2b..02809058fd8097d3eb8c0876498bdb547abb08b7 100644
--- a/caddyhttp/proxy/setup_test.go
+++ b/caddyhttp/proxy/setup_test.go
@@ -131,6 +131,22 @@ func TestSetup(t *testing.T) {
 				"http://localhost:8005/a--b": {},
 			},
 		},
+		// test #12 test value is optional when remove upstream header
+		{
+			"proxy / localhost:1984 {\n header_upstream -server \n}",
+			false,
+			map[string]struct{}{
+				"http://localhost:1984": {},
+			},
+		},
+		// test #13 test value is optional when remove downstream header
+		{
+			"proxy / localhost:1984 {\n header_downstream -server \n}",
+			false,
+			map[string]struct{}{
+				"http://localhost:1984": {},
+			},
+		},
 	} {
 		c := caddy.NewTestController("http", test.input)
 		err := setup(c)
diff --git a/caddyhttp/proxy/upstream.go b/caddyhttp/proxy/upstream.go
index dba4af3c84ca1e264f4fc23d3b85a90e5e3449df..78ed4116e1cb4c817ee844f8fe4927f6100e85f8 100644
--- a/caddyhttp/proxy/upstream.go
+++ b/caddyhttp/proxy/upstream.go
@@ -305,13 +305,19 @@ func parseBlock(c *caddyfile.Dispenser, u *staticUpstream) error {
 	case "header_upstream":
 		var header, value string
 		if !c.Args(&header, &value) {
-			return c.ArgErr()
+			// When removing a header, the value can be optional.
+			if !strings.HasPrefix(header, "-") {
+				return c.ArgErr()
+			}
 		}
 		u.upstreamHeaders.Add(header, value)
 	case "header_downstream":
 		var header, value string
 		if !c.Args(&header, &value) {
-			return c.ArgErr()
+			// When removing a header, the value can be optional.
+			if !strings.HasPrefix(header, "-") {
+				return c.ArgErr()
+			}
 		}
 		u.downstreamHeaders.Add(header, value)
 	case "transparent":