diff --git a/.golangci.reference.yml b/.golangci.reference.yml
index 7de210b98ba4..d98c0cf52730 100644
--- a/.golangci.reference.yml
+++ b/.golangci.reference.yml
@@ -2072,6 +2072,7 @@ linters:
     - predeclared
     - promlinter
     - reassign
+    - responsewriterlint
     - revive
     - rowserrcheck
     - scopelint
diff --git a/go.mod b/go.mod
index 84e4478593de..513942a57bc5 100644
--- a/go.mod
+++ b/go.mod
@@ -48,6 +48,7 @@ require (
 	github.com/hashicorp/go-multierror v1.1.1
 	github.com/hashicorp/go-version v1.6.0
 	github.com/hexops/gotextdiff v1.0.3
+	github.com/javorszky/go-responsewriter-lint v0.1.2
 	github.com/jgautheron/goconst v1.5.1
 	github.com/jingyugao/rowserrcheck v1.1.1
 	github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af
diff --git a/go.sum b/go.sum
index 8bde49ab6f8c..363096f3454a 100644
--- a/go.sum
+++ b/go.sum
@@ -292,6 +292,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
 github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/javorszky/go-responsewriter-lint v0.1.2 h1:tidNkspygGMNpulecVWku/rzt+KkRhu+LuPLgWVjUAo=
+github.com/javorszky/go-responsewriter-lint v0.1.2/go.mod h1:n+m48J/7g3XTWeEE3lnG/hSPVwRPo9ZgT8xpzLu86ks=
 github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM=
 github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
 github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=
diff --git a/pkg/golinters/responsewriterlint.go b/pkg/golinters/responsewriterlint.go
new file mode 100644
index 000000000000..365967de56b4
--- /dev/null
+++ b/pkg/golinters/responsewriterlint.go
@@ -0,0 +1,19 @@
+package golinters
+
+import (
+	"github.com/javorszky/go-responsewriter-lint/pkg/analyzer"
+	"golang.org/x/tools/go/analysis"
+
+	"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
+)
+
+func NewResponseWriterLint() *goanalysis.Linter {
+	a := analyzer.New()
+
+	return goanalysis.NewLinter(
+		a.Name,
+		a.Doc,
+		[]*analysis.Analyzer{a},
+		nil,
+	).WithLoadMode(goanalysis.LoadModeTypesInfo)
+}
diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go
index 6f406f7d26e3..97de628ee939 100644
--- a/pkg/lint/lintersdb/manager.go
+++ b/pkg/lint/lintersdb/manager.go
@@ -722,6 +722,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
 			WithLoadForGoAnalysis().
 			WithURL("https://github.com/curioswitch/go-reassign"),
 
+		linter.NewConfig(golinters.NewResponseWriterLint()).
+			WithSince("1.52.0").
+			WithPresets(linter.PresetBugs).
+			WithLoadForGoAnalysis().
+			WithURL("https://github.com/javorszky/go-responsewriter-lint"),
+
 		linter.NewConfig(golinters.NewRevive(reviveCfg)).
 			WithSince("v1.37.0").
 			WithPresets(linter.PresetStyle, linter.PresetMetaLinter).
diff --git a/test/testdata/responsewriterlint.go b/test/testdata/responsewriterlint.go
new file mode 100644
index 000000000000..6e27ee927e63
--- /dev/null
+++ b/test/testdata/responsewriterlint.go
@@ -0,0 +1,66 @@
+//golangcitest:args -Eresponsewriterlint
+package testdata
+
+import (
+	"errors"
+	"fmt"
+	"net/http"
+)
+
+type notAResponseWriter struct{}
+
+func (narw notAResponseWriter) Write(in []byte) (int, error) {
+	// actually do nothing
+	return 42, errors.New("no")
+}
+
+func (narw notAResponseWriter) WriteHeader(code int) {
+	// also do nothing
+}
+
+func (narw notAResponseWriter) Header() http.Header {
+	return http.Header{}
+}
+
+type rwlRandom struct{}
+
+func rwlExampleOne(w http.ResponseWriter, r *http.Request) {
+	w.Header().Add("some header", "value")
+	w.WriteHeader(http.StatusOK)
+	_, _ = w.Write([]byte(`boys in the yard`))
+}
+
+func rwlExampleTwo(s string, r *http.Request) error {
+	fmt.Printf("this is a thing")
+
+	return nil
+}
+
+func rwlFakeWriter(w notAResponseWriter) {
+	w.Header().Add("something", "other")
+	w.WriteHeader(420)
+	_, _ = w.Write([]byte(`fooled ya`))
+}
+
+func (b rwlRandom) method(w http.ResponseWriter, r *http.Request) {
+	w.Header().Add("some header", "value")
+	w.WriteHeader(http.StatusOK)
+	_, _ = w.Write([]byte(`boys in the yard`))
+}
+
+func (b *rwlRandom) methodPointer(w http.ResponseWriter, r *http.Request) {
+	w.Header().Add("some header", "value")
+	_, _ = w.Write([]byte(`boys in the yard`))
+	w.WriteHeader(http.StatusOK) // want "function methodPointer: http.ResponseWriter.Write is called before http.ResponseWriter.WriteHeader. Headers are already sent, this has no effect."
+}
+
+func rwlExampleThree(bloe http.ResponseWriter, r *http.Request) {
+	_, _ = bloe.Write([]byte(`hellyea`)) // want "function rwlExampleThree: Multiple calls to http.ResponseWriter.Write in the same function body. This is most probably a bug."
+
+	bloe.WriteHeader(http.StatusBadRequest)          // want "function rwlExampleThree: Multiple calls to http.ResponseWriter.WriteHeader in the same function body. This is most probably a bug."
+	_, _ = bloe.Write([]byte(`hellyelamdflmda`))     // want "function rwlExampleThree: Multiple calls to http.ResponseWriter.Write in the same function body. This is most probably a bug."
+	bloe.WriteHeader(http.StatusInternalServerError) // want "function rwlExampleThree: Multiple calls to http.ResponseWriter.WriteHeader in the same function body. This is most probably a bug."
+
+	bloe.Header().Set("help", "somebody")     // want "function rwlExampleThree: http.ResponseWriter.Header called after calling http.ResponseWriter.Write. This has no effect." "function rwlExampleThree: http.ResponseWriter.Header called after calling http.ResponseWriter.Write. This has no effect." "function rwlExampleThree: http.ResponseWriter.Header called after calling http.ResponseWriter.WriteHeader. This has no effect." "function rwlExampleThree: http.ResponseWriter.Header called after calling http.ResponseWriter.WriteHeader. This has no effect."
+	bloe.Header().Set("dddd", "someboddaady") // want "function rwlExampleThree: http.ResponseWriter.Header called after calling http.ResponseWriter.Write. This has no effect." "function rwlExampleThree: http.ResponseWriter.Header called after calling http.ResponseWriter.Write. This has no effect." "function rwlExampleThree: http.ResponseWriter.Header called after calling http.ResponseWriter.WriteHeader. This has no effect." "function rwlExampleThree: http.ResponseWriter.Header called after calling http.ResponseWriter.WriteHeader. This has no effect."
+}