diff --git a/src/mime/multipart/multipart.go b/src/mime/multipart/multipart.go
index 17088bc30e1b43..6379dfbe973763 100644
--- a/src/mime/multipart/multipart.go
+++ b/src/mime/multipart/multipart.go
@@ -331,6 +331,11 @@ func (p *Part) Close() error {
 // Reader's underlying parser consumes its input as needed. Seeking
 // isn't supported.
 type Reader struct {
+	// MaxMIMEHeaderSize is the maximum size of a MIME header we will parse,
+	// including header keys, values, and map overhead. If not set, then the
+	// default value of 10 << 20 is used.
+	MaxMIMEHeaderSize int64
+
 	bufReader *bufio.Reader
 	tempDir   string // used in tests
 
@@ -362,6 +367,17 @@ func maxMIMEHeaders() int64 {
 	return 10000
 }
 
+// maxMIMEHeaderSize returns the maximum size of a MIME header we will parse.
+// It uses the value of Reader.MaxMIMEHeaderSize if it is not 0, otherwise the
+// value of maxMIMEHeaderSize constant is used.
+func (r *Reader) maxMIMEHeaderSize() int64 {
+	if r.MaxMIMEHeaderSize != 0 {
+		return r.MaxMIMEHeaderSize
+	} else {
+		return maxMIMEHeaderSize
+	}
+}
+
 // NextPart returns the next part in the multipart or an error.
 // When there are no more parts, the error [io.EOF] is returned.
 //
@@ -369,7 +385,7 @@ func maxMIMEHeaders() int64 {
 // has a value of "quoted-printable", that header is instead
 // hidden and the body is transparently decoded during Read calls.
 func (r *Reader) NextPart() (*Part, error) {
-	return r.nextPart(false, maxMIMEHeaderSize, maxMIMEHeaders())
+	return r.nextPart(false, r.maxMIMEHeaderSize(), maxMIMEHeaders())
 }
 
 // NextRawPart returns the next part in the multipart or an error.
@@ -378,7 +394,7 @@ func (r *Reader) NextPart() (*Part, error) {
 // Unlike [Reader.NextPart], it does not have special handling for
 // "Content-Transfer-Encoding: quoted-printable".
 func (r *Reader) NextRawPart() (*Part, error) {
-	return r.nextPart(true, maxMIMEHeaderSize, maxMIMEHeaders())
+	return r.nextPart(true, r.maxMIMEHeaderSize(), maxMIMEHeaders())
 }
 
 func (r *Reader) nextPart(rawPart bool, maxMIMEHeaderSize, maxMIMEHeaders int64) (*Part, error) {
diff --git a/src/mime/multipart/multipart_test.go b/src/mime/multipart/multipart_test.go
index e0cb768c6967a5..b7bbf5ae320cab 100644
--- a/src/mime/multipart/multipart_test.go
+++ b/src/mime/multipart/multipart_test.go
@@ -931,6 +931,41 @@ Cases:
 	}
 }
 
+func TestParseMaxMIMEHeaderSize(t *testing.T) {
+	sep := "MyBoundary"
+	in := `This is a multi-part message.  This line is ignored.
+--MyBoundary
+Header1: value1
+Header2: value2
+Header3: value3
+Header4: value4
+Header5: value5
+Header6: value6
+Header7: value7
+Header8: value8
+
+My value
+The end.
+--MyBoundary--`
+
+	in = strings.Replace(in, "\n", "\r\n", -1)
+
+	// Control.
+	r := NewReader(strings.NewReader(in), sep)
+	_, err := r.NextPart()
+	if err != nil {
+		t.Fatalf("control failed: %v", err)
+	}
+
+	// Test MaxMIMEHeaderSize.
+	r = NewReader(strings.NewReader(in), sep)
+	r.MaxMIMEHeaderSize = 100
+	_, err = r.NextPart()
+	if err != ErrMessageTooLarge {
+		t.Fatalf("test failed: %v", err)
+	}
+}
+
 func partsFromReader(r *Reader) ([]headerBody, error) {
 	got := []headerBody{}
 	for {