diff --git a/goatherd.go b/goatherd.go
index 2607bfa4475b390a22dc363bd45f8918d407887a..cc57237ca26ffa07d5c5005eceb1558cf28f9caf 100644
--- a/goatherd.go
+++ b/goatherd.go
@@ -185,7 +185,7 @@ func readUsersFromFile(path string) {
 			name   string
 			secret []byte
 		}
-		err = rows.Scan(&have.name, &have.secret)
+		_ = rows.Scan(&have.name, &have.secret)
 		debug("have", have.name)
 
 		if sB64, want := usersWant[have.name]; want {
@@ -303,7 +303,7 @@ func checkOffer(remote string, name string, offer string) (bool, error) {
 		if transactionFailed(err) {
 			goto retry
 		} else if err == sql.ErrNoRows {
-			tx.Rollback()
+			_ = tx.Rollback()
 			return false, err
 		} else {
 			errPanic(err)
@@ -342,9 +342,9 @@ func checkOffer(remote string, name string, offer string) (bool, error) {
 
 	retry:
 		debugf("[%v] retry", remote)
-		ok = false
-		err = nil
-		tx.Rollback()
+		ok = false // nolint: ineffassign
+		err = nil  // nolint: ineffassign
+		_ = tx.Rollback()
 	}
 }
 
@@ -517,7 +517,7 @@ func incCount(user string, diff uint64) error {
 		if transactionFailed(err) {
 			goto retry
 		} else if err != nil {
-			tx.Rollback()
+			_ = tx.Rollback()
 			return err
 		}
 
@@ -525,15 +525,14 @@ func incCount(user string, diff uint64) error {
 		if transactionFailed(err) {
 			goto retry
 		} else if err != nil {
-			tx.Rollback()
+			_ = tx.Rollback()
 			return err
 		}
 
-		tx.Commit()
-		return nil
+		return tx.Commit()
 
 	retry:
-		tx.Rollback()
+		_ = tx.Rollback()
 	}
 }
 
@@ -616,7 +615,7 @@ func main() {
 			flagAddr := fs.String("addr", "", "Address to listen on. (default 127.0.0.1:9999)")
 			flagTLSKey := fs.String("tls-key", "", "Use TLS.")
 			flagTLSCert := fs.String("tls-cert", "", "Use TLS.")
-			fs.Parse(args)
+			errFatal(fs.Parse(args))
 
 			// copy -addr option to config
 			if *flagAddr != "" {
diff --git a/goatherd_test.go b/goatherd_test.go
index 90c658fd10aa41a3802a74208db58427bb8bb102..3cf8748f5181f628ac9a8e5b3cf7beb7aae6e121 100644
--- a/goatherd_test.go
+++ b/goatherd_test.go
@@ -47,7 +47,7 @@ func createAndCheck(user string, sec string) func(*testing.T) {
 		})
 
 		t.Run("correctSecret", func(t *testing.T) {
-			if bytes.Compare(secret, result.secret) != 0 {
+			if !bytes.Equal(secret, result.secret) {
 				t.Errorf("secret: %v; result: %v", string(secret), string(result.secret))
 			}
 		})
@@ -88,7 +88,7 @@ func interleavedTransactionsT(t *testing.T) {
 	for i := range txs {
 		txs[i], err = db.Begin()
 		tErrFatal(t, err)
-		defer func(i int) { txs[i].Rollback() }(i)
+		defer func(i int) { _ = txs[i].Rollback() }(i)
 	}
 
 	var c uint64
@@ -119,10 +119,10 @@ func interleavedTransactionsT(t *testing.T) {
 func nestedTransactionsT(t *testing.T) {
 	outer, err := db.Begin()
 	tErrFatal(t, err)
-	defer outer.Rollback()
+	defer func() { _ = outer.Rollback() }()
 	inner, err := db.Begin()
 	tErrFatal(t, err)
-	defer inner.Rollback()
+	defer func() { _ = inner.Rollback() }()
 
 	var c uint64
 	tErrFatal(t, outer.QueryRow("SELECT count FROM users WHERE name = $1", username).Scan(&c))
@@ -259,8 +259,8 @@ func mockConn(client mockClient) (delay *sync.Mutex) {
 
 func interact(name string, offer string, recv chan string) mockClient {
 	return func(r *io.PipeReader, w *io.PipeWriter) {
-		w.Write(append([]byte(name), '\n'))
-		w.Write(append([]byte(offer), '\n'))
+		_, _ = w.Write(append([]byte(name), '\n'))
+		_, _ = w.Write(append([]byte(offer), '\n'))
 		answer, _ := getLine(bufio.NewScanner(r))
 		recv <- answer
 	}
@@ -341,7 +341,7 @@ func handleConnT(t *testing.T) {
 
 		t.Run("closeAfterUsername", func(t *testing.T) {
 			delay := mockConn(func(r *io.PipeReader, w *io.PipeWriter) {
-				w.Write(append([]byte(username), '\n'))
+				_, _ = w.Write(append([]byte(username), '\n'))
 				w.Close()
 			})
 			if delay != nil {
@@ -357,8 +357,8 @@ func handleConnT(t *testing.T) {
 		t.Run("FAIL", func(t *testing.T) {
 			delay := mockConn(func(r *io.PipeReader, w *io.PipeWriter) {
 				r.Close()
-				w.Write(append([]byte(username), '\n'))
-				w.Write(append([]byte("dummy offer"), '\n'))
+				_, _ = w.Write(append([]byte(username), '\n'))
+				_, _ = w.Write(append([]byte("dummy offer"), '\n'))
 			})
 			if delay == nil {
 				t.Fail()
@@ -372,8 +372,8 @@ func handleConnT(t *testing.T) {
 		t.Run("OK", func(t *testing.T) {
 			delay := mockConn(func(r *io.PipeReader, w *io.PipeWriter) {
 				r.Close()
-				w.Write(append([]byte(username), '\n'))
-				w.Write(append([]byte(otp.OTP()), '\n'))
+				_, _ = w.Write(append([]byte(username), '\n'))
+				_, _ = w.Write(append([]byte(otp.OTP()), '\n'))
 			})
 			if delay != nil {
 				t.Fail()
@@ -395,7 +395,7 @@ func listenT(t *testing.T) {
 		start := time.Now()
 		for {
 			if _, err = c.Write([]byte("a")); err != nil {
-				t.Logf("Write failed after %v with %q", time.Now().Sub(start), err)
+				t.Logf("Write failed after %v with %q", time.Since(start), err)
 				break
 			}
 			time.Sleep(200 * time.Millisecond)