diff --git a/.changelog/12021.txt b/.changelog/12021.txt
new file mode 100644
index 00000000000..2d34a105619
--- /dev/null
+++ b/.changelog/12021.txt
@@ -0,0 +1,3 @@
+```release-note:improvement
+client: Allow interpolation of the network.dns block
+```
diff --git a/client/taskenv/network.go b/client/taskenv/network.go
index 3bbafaa0c11..7d9b2a0f81a 100644
--- a/client/taskenv/network.go
+++ b/client/taskenv/network.go
@@ -9,6 +9,7 @@ import (
 //
 // Current interoperable fields:
 //   - Hostname
+//   - DNS
 func InterpolateNetworks(taskEnv *TaskEnv, networks structs.Networks) structs.Networks {
 
 	// Guard against not having a valid taskEnv. This can be the case if the
@@ -23,6 +24,11 @@ func InterpolateNetworks(taskEnv *TaskEnv, networks structs.Networks) structs.Ne
 	// Iterate the copy and perform the interpolation.
 	for i := range interpolated {
 		interpolated[i].Hostname = taskEnv.ReplaceEnv(interpolated[i].Hostname)
+		if interpolated[i].DNS != nil {
+			interpolated[i].DNS.Servers = taskEnv.ParseAndReplace(interpolated[i].DNS.Servers)
+			interpolated[i].DNS.Searches = taskEnv.ParseAndReplace(interpolated[i].DNS.Searches)
+			interpolated[i].DNS.Options = taskEnv.ParseAndReplace(interpolated[i].DNS.Options)
+		}
 	}
 
 	return interpolated
diff --git a/client/taskenv/network_test.go b/client/taskenv/network_test.go
index 60589b6f1c3..ec892d4d317 100644
--- a/client/taskenv/network_test.go
+++ b/client/taskenv/network_test.go
@@ -34,6 +34,50 @@ func Test_InterpolateNetworks(t *testing.T) {
 			},
 			name: "interpolated hostname",
 		},
+		{
+			inputTaskEnv: testEnv,
+			inputNetworks: structs.Networks{
+				{
+					DNS: &structs.DNSConfig{
+						Servers:  []string{"127.0.0.1"},
+						Options:  []string{"some-opt"},
+						Searches: []string{"example.com"},
+					},
+				},
+			},
+			expectedOutputNetworks: structs.Networks{
+				{
+					DNS: &structs.DNSConfig{
+						Servers:  []string{"127.0.0.1"},
+						Options:  []string{"some-opt"},
+						Searches: []string{"example.com"},
+					},
+				},
+			},
+			name: "non-interpolated dns servers",
+		},
+		{
+			inputTaskEnv: testEnv,
+			inputNetworks: structs.Networks{
+				{
+					DNS: &structs.DNSConfig{
+						Servers:  []string{"${foo}"},
+						Options:  []string{"${foo}-opt"},
+						Searches: []string{"${foo}.example.com"},
+					},
+				},
+			},
+			expectedOutputNetworks: structs.Networks{
+				{
+					DNS: &structs.DNSConfig{
+						Servers:  []string{"bar"},
+						Options:  []string{"bar-opt"},
+						Searches: []string{"bar.example.com"},
+					},
+				},
+			},
+			name: "interpolated dns servers",
+		},
 	}
 
 	for _, tc := range testCases {
diff --git a/website/content/docs/job-specification/network.mdx b/website/content/docs/job-specification/network.mdx
index 1e8a88d0a5f..c107e8166ef 100644
--- a/website/content/docs/job-specification/network.mdx
+++ b/website/content/docs/job-specification/network.mdx
@@ -120,6 +120,8 @@ The label of the port is just text - it has no special meaning to Nomad.
 - `searches` `(array<string>: nil)` - Sets the search list for hostname lookup
 - `options` `(array<string>: nil)` - Sets internal resolver variables.
 
+These parameters support [interpolation](/docs/runtime/interpolation).
+
 ## `network` Examples
 
 The following examples only show the `network` stanzas. Remember that the