Repository: kubernetes-sigs/aws-iam-authenticator

Issue:
Possible nil pointer dereference
https://github.com/kubernetes-sigs/aws-iam-authenticator/blob/e61f537662b64092ed83cb76e600e023f627f628/pkg/token/token.go#L507-L509

The error from `http.NewRequest` is not being checked, so it is possible for `req` to be `nil`.

Discussion:
@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue or PR as fresh with `/remove-lifecycle stale`
- Mark this issue or PR as rotten with `/lifecycle rotten`
- Close this issue or PR with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue or PR as fresh with `/remove-lifecycle stale`
- Mark this issue or PR as rotten with `/lifecycle rotten`
- Close this issue or PR with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue or PR as fresh with `/remove-lifecycle stale`
- Mark this issue or PR as rotten with `/lifecycle rotten`
- Close this issue or PR with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue or PR as fresh with `/remove-lifecycle stale`
- Mark this issue or PR as rotten with `/lifecycle rotten`
- Close this issue or PR with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@k8s-triage-robot: The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue or PR as fresh with `/remove-lifecycle rotten`
- Close this issue or PR with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle rotten

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle rotten@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle stale`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle stale`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle stale`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle stale`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle stale`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle stale`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle stale`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle stale`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@rittneje: /remove-lifecycle stale

Solution patch:
diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml
index 64e709e1..3438b10b 100644
--- a/.github/workflows/create-release.yml
+++ b/.github/workflows/create-release.yml
@@ -31,6 +31,8 @@ jobs:
 
       - name: Set up Go
         uses: actions/setup-go@v6
+        with:
+          go-version-file: .go-version
 
       - name: Run GoReleaser
         uses: goreleaser/goreleaser-action@v6
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
new file mode 100644
index 00000000..511cd5e7
--- /dev/null
+++ b/.github/workflows/pr.yml
@@ -0,0 +1,25 @@
+name: Pull request checks
+
+on:
+  pull_request:
+  workflow_dispatch:
+
+permissions:
+  contents: read
+
+jobs:
+  golangci-lint:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v5
+
+      - name: Setup Go
+        uses: actions/setup-go@v6
+        with:
+          go-version-file: .go-version
+
+      - name: Lint
+        uses: golangci/golangci-lint-action@v8.0.0
+        with:
+          version: v2.4.0
diff --git a/cmd/aws-iam-authenticator/init.go b/cmd/aws-iam-authenticator/init.go
index 7c4b5dc0..3695649d 100644
--- a/cmd/aws-iam-authenticator/init.go
+++ b/cmd/aws-iam-authenticator/init.go
@@ -77,13 +77,19 @@ func init() {
 		"hostname",
 		"localhost",
 		"Hostname that should be used for writing the self-signed certificates")
-	viper.BindPFlag("server.hostname", initCmd.Flags().Lookup("hostname"))
+	if err := viper.BindPFlag("server.hostname", initCmd.Flags().Lookup("hostname")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.hostname", err)
+		os.Exit(1)
+	}
 
 	initCmd.Flags().String(
 		"address",
 		"127.0.0.1",
 		"IP Address to bind the server to listen to. (should be a 127.0.0.1 or 0.0.0.0)")
-	viper.BindPFlag("server.address", initCmd.Flags().Lookup("address"))
+	if err := viper.BindPFlag("server.address", initCmd.Flags().Lookup("address")); err != nil {
+		fmt.Printf("Failed to bind env '%s' - %+v\n", "server.address", err)
+		os.Exit(1)
+	}
 
 	rootCmd.AddCommand(initCmd)
 }
diff --git a/cmd/aws-iam-authenticator/root.go b/cmd/aws-iam-authenticator/root.go
index a6b9ae83..1a9de27e 100644
--- a/cmd/aws-iam-authenticator/root.go
+++ b/cmd/aws-iam-authenticator/root.go
@@ -63,21 +63,40 @@ func init() {
 
 	rootCmd.PersistentFlags().StringP("log-verbosity", "v", "info",
 		"Specify log level to use when logging to stderr ["+strings.Join(getValidLogLevels(), ", ")+"]")
-	viper.BindPFlag("log-verbosity", rootCmd.PersistentFlags().Lookup("log-verbosity"))
-	viper.BindEnv("log-verbosity", "AWS_IAM_AUTHENTICATOR_LOG_VERBOSITY")
+	if err := viper.BindPFlag("log-verbosity", rootCmd.PersistentFlags().Lookup("log-verbosity")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "log-verbosity", err)
+		os.Exit(1)
+	}
+
+	if err := viper.BindEnv("log-verbosity", "AWS_IAM_AUTHENTICATOR_LOG_VERBOSITY"); err != nil {
+		fmt.Printf("Failed to bind env '%s' - %+v\n", "log-verbosity", err)
+		os.Exit(1)
+	}
 
 	rootCmd.PersistentFlags().StringP(
 		"cluster-id",
 		"i",
 		"",
 		"Specify the cluster `ID`, a unique-per-cluster identifier for your aws-iam-authenticator installation.")
-	viper.BindPFlag("clusterID", rootCmd.PersistentFlags().Lookup("cluster-id"))
-	viper.BindEnv("clusterID", "KUBERNETES_AWS_AUTHENTICATOR_CLUSTER_ID")
+	if err := viper.BindPFlag("clusterID", rootCmd.PersistentFlags().Lookup("cluster-id")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "clusterID", err)
+		os.Exit(1)
+	}
+	if err := viper.BindEnv("clusterID", "KUBERNETES_AWS_AUTHENTICATOR_CLUSTER_ID"); err != nil {
+		fmt.Printf("Failed to bind env '%s' - %+v\n", "clusterID", err)
+		os.Exit(1)
+	}
 
-	featureGates.Add(config.DefaultFeatureGates)
+	if err := featureGates.Add(config.DefaultFeatureGates); err != nil {
+		fmt.Printf("Failed to add feature gates - %+v\n", err)
+		os.Exit(1)
+	}
 	featureGates.AddFlag(rootCmd.PersistentFlags())
 
-	viper.BindPFlag("feature-gates", rootCmd.PersistentFlags().Lookup("feature-gates"))
+	if err := viper.BindPFlag("feature-gates", rootCmd.PersistentFlags().Lookup("feature-gates")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "feature-gates", err)
+		os.Exit(1)
+	}
 }
 
 func initConfig() {
@@ -159,7 +178,7 @@ func getConfig() (config.Config, error) {
 	}
 
 	if !slices.Contains(endpoints.PARTITIONS, cfg.PartitionID) {
-		return cfg, errors.New("Invalid partition")
+		return cfg, errors.New("invalid partition")
 	}
 
 	// DynamicFile BackendMode and DynamicFilePath are mutually inclusive.
diff --git a/cmd/aws-iam-authenticator/server.go b/cmd/aws-iam-authenticator/server.go
index 389ce70c..b719b2d9 100644
--- a/cmd/aws-iam-authenticator/server.go
+++ b/cmd/aws-iam-authenticator/server.go
@@ -21,6 +21,7 @@ package main
 import (
 	"flag"
 	"fmt"
+	"os"
 	"strings"
 
 	"k8s.io/sample-controller/pkg/signals"
@@ -70,59 +71,92 @@ func init() {
 	serverCmd.Flags().String("partition",
 		endpoints.AwsPartitionID,
 		fmt.Sprintf("The AWS partition. Must be one of: %v", endpoints.PARTITIONS))
-	viper.BindPFlag("server.partition", serverCmd.Flags().Lookup("partition"))
+	if err := viper.BindPFlag("server.partition", serverCmd.Flags().Lookup("partition")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.partition", err)
+		os.Exit(1)
+	}
 
 	serverCmd.Flags().String("generate-kubeconfig",
 		"/etc/kubernetes/aws-iam-authenticator/kubeconfig.yaml",
 		"Output `path` where a generated webhook kubeconfig (for `--authentication-token-webhook-config-file`) will be stored.  When running as a container, this should be a hostPath mount and the API server must be able to access the file.")
-	viper.BindPFlag("server.generateKubeconfig", serverCmd.Flags().Lookup("generate-kubeconfig"))
+	if err := viper.BindPFlag("server.generateKubeconfig", serverCmd.Flags().Lookup("generate-kubeconfig")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.generateKubeconfig", err)
+		os.Exit(1)
+	}
 
 	serverCmd.Flags().Bool("kubeconfig-pregenerated",
 		false,
 		"Set to `true` when a webhook kubeconfig is pre-generated by running the `init` command, and therefore the `server` shouldn't unnecessarily re-generate a new one.")
-	viper.BindPFlag("server.kubeconfigPregenerated", serverCmd.Flags().Lookup("kubeconfig-pregenerated"))
+	if err := viper.BindPFlag("server.kubeconfigPregenerated", serverCmd.Flags().Lookup("kubeconfig-pregenerated")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.kubeconfigPregenerated", err)
+		os.Exit(1)
+	}
 
 	serverCmd.Flags().String("state-dir",
 		"/var/aws-iam-authenticator",
 		"State `directory` for generated certificate and private key.  When running as a container, this should be a hostPath mount so that the certificate and key persisted across resarts.")
-	viper.BindPFlag("server.stateDir", serverCmd.Flags().Lookup("state-dir"))
+	if err := viper.BindPFlag("server.stateDir", serverCmd.Flags().Lookup("state-dir")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.stateDir", err)
+		os.Exit(1)
+	}
 
 	serverCmd.Flags().String("kubeconfig",
 		"",
 		"kubeconfig file path for using a local kubeconfig to configure the client to talk to the API server for CRD and EKSConfigMap backends.")
-	viper.BindPFlag("server.kubeconfig", serverCmd.Flags().Lookup("kubeconfig"))
+	if err := viper.BindPFlag("server.kubeconfig", serverCmd.Flags().Lookup("kubeconfig")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.kubeconfig", err)
+		os.Exit(1)
+	}
 	serverCmd.Flags().String("master",
 		"",
 		"master is the URL to the api server, which is merged with the kubeconfig for CRD and EKSConfigMap backends.")
-	viper.BindPFlag("server.master", serverCmd.Flags().Lookup("master"))
+	if err := viper.BindPFlag("server.master", serverCmd.Flags().Lookup("master")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.master", err)
+		os.Exit(1)
+	}
 
 	serverCmd.Flags().String("address",
 		"127.0.0.1",
 		"IP Address to bind the aws-iam-authenticator server to listen to. For example: 127.0.0.1 or 0.0.0.0")
-	viper.BindPFlag("server.address", serverCmd.Flags().Lookup("address"))
+	if err := viper.BindPFlag("server.address", serverCmd.Flags().Lookup("address")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.address", err)
+		os.Exit(1)
+	}
 
 	serverCmd.Flags().StringSlice("backend-mode",
 		[]string{mapper.ModeMountedFile},
 		fmt.Sprintf("Ordered list of backends to get mappings from. The first one that returns a matching mapping wins. Comma-delimited list of: %s", strings.Join(mapper.BackendModeChoices, ",")))
-	viper.BindPFlag("server.backendMode", serverCmd.Flags().Lookup("backend-mode"))
+	if err := viper.BindPFlag("server.backendMode", serverCmd.Flags().Lookup("backend-mode")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.backendMode", err)
+		os.Exit(1)
+	}
 
 	serverCmd.Flags().Int(
 		"port",
 		DefaultPort,
 		"Port to bind the server to listen to")
-	viper.BindPFlag("server.port", serverCmd.Flags().Lookup("port"))
+	if err := viper.BindPFlag("server.port", serverCmd.Flags().Lookup("port")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.port", err)
+		os.Exit(1)
+	}
 
 	serverCmd.Flags().Int(
 		"ec2-describeInstances-qps",
 		DefaultEC2DescribeInstancesQps,
 		"AWS EC2 rate limiting with qps")
-	viper.BindPFlag("server.ec2DescribeInstancesQps", serverCmd.Flags().Lookup("ec2-describeInstances-qps"))
+	if err := viper.BindPFlag("server.ec2DescribeInstancesQps", serverCmd.Flags().Lookup("ec2-describeInstances-qps")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.ec2DescribeInstancesQps", err)
+		os.Exit(1)
+	}
 
 	serverCmd.Flags().Int(
 		"ec2-describeInstances-burst",
 		DefaultEC2DescribeInstancesBurst,
 		"AWS EC2 rate Limiting with burst")
-	viper.BindPFlag("server.ec2DescribeInstancesBurst", serverCmd.Flags().Lookup("ec2-describeInstances-burst"))
+	if err := viper.BindPFlag("server.ec2DescribeInstancesBurst", serverCmd.Flags().Lookup("ec2-describeInstances-burst")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "server.ec2DescribeInstancesBurst", err)
+		os.Exit(1)
+	}
 
 	fs := flag.NewFlagSet("", flag.ContinueOnError)
 	_ = fs.Parse([]string{})
diff --git a/cmd/aws-iam-authenticator/token.go b/cmd/aws-iam-authenticator/token.go
index 29b8ae15..50d87483 100644
--- a/cmd/aws-iam-authenticator/token.go
+++ b/cmd/aws-iam-authenticator/token.go
@@ -45,13 +45,17 @@ var tokenCmd = &cobra.Command{
 
 		if clusterID == "" {
 			fmt.Fprintf(os.Stderr, "Error: cluster ID not specified\n")
-			cmd.Usage()
+			if err := cmd.Usage(); err != nil {
+				fmt.Fprintf(os.Stderr, "Error displaying usage: %v\n", err)
+			}
 			os.Exit(1)
 		}
 
 		if forwardSessionName && sessionName != "" {
 			fmt.Fprintf(os.Stderr, "Error: cannot specify both --forward-session-name and --session-name parameter\n")
-			cmd.Usage()
+			if err := cmd.Usage(); err != nil {
+				fmt.Fprintf(os.Stderr, "Error displaying usage: %v\n", err)
+			}
 			os.Exit(1)
 		}
 
@@ -95,12 +99,36 @@ func init() {
 		false,
 		"Enable mapping a federated sessions caller-specified-role-name attribute onto newly assumed sessions. NOTE: Only applicable when a new role is requested via --role")
 	tokenCmd.Flags().Bool("cache", false, "Cache the credential on disk until it expires. Uses the aws profile specified by AWS_PROFILE or the default profile.")
-	viper.BindPFlag("region", tokenCmd.Flags().Lookup("region"))
-	viper.BindPFlag("role", tokenCmd.Flags().Lookup("role"))
-	viper.BindPFlag("externalID", tokenCmd.Flags().Lookup("external-id"))
-	viper.BindPFlag("tokenOnly", tokenCmd.Flags().Lookup("token-only"))
-	viper.BindPFlag("forwardSessionName", tokenCmd.Flags().Lookup("forward-session-name"))
-	viper.BindPFlag("sessionName", tokenCmd.Flags().Lookup("session-name"))
-	viper.BindPFlag("cache", tokenCmd.Flags().Lookup("cache"))
-	viper.BindEnv("role", "DEFAULT_ROLE")
+	if err := viper.BindPFlag("region", tokenCmd.Flags().Lookup("region")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "region", err)
+		os.Exit(1)
+	}
+	if err := viper.BindPFlag("role", tokenCmd.Flags().Lookup("role")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "role", err)
+		os.Exit(1)
+	}
+	if err := viper.BindPFlag("externalID", tokenCmd.Flags().Lookup("external-id")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "externalID", err)
+		os.Exit(1)
+	}
+	if err := viper.BindPFlag("tokenOnly", tokenCmd.Flags().Lookup("token-only")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "tokenOnly", err)
+		os.Exit(1)
+	}
+	if err := viper.BindPFlag("forwardSessionName", tokenCmd.Flags().Lookup("forward-session-name")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "forwardSessionName", err)
+		os.Exit(1)
+	}
+	if err := viper.BindPFlag("sessionName", tokenCmd.Flags().Lookup("session-name")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "sessionName", err)
+		os.Exit(1)
+	}
+	if err := viper.BindPFlag("cache", tokenCmd.Flags().Lookup("cache")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "cache", err)
+		os.Exit(1)
+	}
+	if err := viper.BindEnv("role", "DEFAULT_ROLE"); err != nil {
+		fmt.Printf("Failed to bind env '%s' - %+v\n", "role", err)
+		os.Exit(1)
+	}
 }
diff --git a/cmd/aws-iam-authenticator/verify.go b/cmd/aws-iam-authenticator/verify.go
index c01f0e04..cd67e293 100644
--- a/cmd/aws-iam-authenticator/verify.go
+++ b/cmd/aws-iam-authenticator/verify.go
@@ -45,13 +45,17 @@ var verifyCmd = &cobra.Command{
 
 		if tok == "" {
 			fmt.Fprintf(os.Stderr, "error: token not specified\n")
-			cmd.Usage()
+			if err := cmd.Usage(); err != nil {
+				fmt.Fprintf(os.Stderr, "Error displaying usage: %v\n", err)
+			}
 			os.Exit(1)
 		}
 
 		if clusterID == "" {
 			fmt.Fprintf(os.Stderr, "error: cluster ID not specified\n")
-			cmd.Usage()
+			if err := cmd.Usage(); err != nil {
+				fmt.Fprintf(os.Stderr, "Error displaying usage: %v\n", err)
+			}
 			os.Exit(1)
 		}
 
@@ -79,13 +83,22 @@ func init() {
 	rootCmd.AddCommand(verifyCmd)
 	verifyCmd.Flags().StringP("token", "t", "", "Token to verify")
 	verifyCmd.Flags().StringP("output", "o", "", "Output format. Only `json` is supported currently.")
-	viper.BindPFlag("token", verifyCmd.Flags().Lookup("token"))
-	viper.BindPFlag("output", verifyCmd.Flags().Lookup("output"))
+	if err := viper.BindPFlag("token", verifyCmd.Flags().Lookup("token")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "token", err)
+		os.Exit(1)
+	}
+	if err := viper.BindPFlag("output", verifyCmd.Flags().Lookup("output")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "output", err)
+		os.Exit(1)
+	}
 
 	verifyCmd.Flags().String("partition",
 		endpoints.AwsPartitionID,
 		fmt.Sprintf("The AWS partition. Must be one of: %v", endpoints.PARTITIONS))
-	viper.BindPFlag("partition", verifyCmd.Flags().Lookup("partition"))
+	if err := viper.BindPFlag("partition", verifyCmd.Flags().Lookup("partition")); err != nil {
+		fmt.Printf("Failed to bind flag '%s' - %+v\n", "partition", err)
+		os.Exit(1)
+	}
 
 }
 
diff --git a/cmd/aws-iam-authenticator/version.go b/cmd/aws-iam-authenticator/version.go
index 2f661754..619f0119 100644
--- a/cmd/aws-iam-authenticator/version.go
+++ b/cmd/aws-iam-authenticator/version.go
@@ -29,13 +29,18 @@ var (
 			case shortened:
 				fmt.Println(pkg.Version)
 			case output == "json":
-				json.NewEncoder(os.Stdout).Encode(ver)
+				if err := json.NewEncoder(os.Stdout).Encode(ver); err != nil {
+					fmt.Fprintf(os.Stderr, "Failed to encode version info to JSON - %+v\n", err)
+					os.Exit(1)
+				}
 			case output == "yaml":
-				yaml.NewEncoder(os.Stdout).Encode(ver)
+				if err := yaml.NewEncoder(os.Stdout).Encode(ver); err != nil {
+					fmt.Fprintf(os.Stderr, "Failed to encode version info to YAML - %+v\n", err)
+					os.Exit(1)
+				}
 			default:
 				fmt.Fprintln(os.Stderr, "unknown version option")
 			}
-			return
 		},
 	}
 )
diff --git a/pkg/arn/arnlike.go b/pkg/arn/arnlike.go
index c9e46cb5..049776ec 100644
--- a/pkg/arn/arnlike.go
+++ b/pkg/arn/arnlike.go
@@ -1,6 +1,7 @@
 package arn
 
 import (
+	"errors"
 	"fmt"
 	"regexp"
 	"strings"
@@ -12,11 +13,11 @@ const (
 	arnPrefix           = "arn:"
 
 	// zero-indexed
-	sectionPartition = 1
-	sectionService   = 2
-	sectionRegion    = 3
-	sectionAccountID = 4
-	sectionResource  = 5
+	// sectionPartition = 1
+	// sectionService   = 2
+	// sectionRegion    = 3
+	// sectionAccountID = 4
+	// sectionResource  = 5
 
 	// errors
 	invalidPrefix   = "invalid prefix"
@@ -30,11 +31,11 @@ func ArnLike(arn, pattern string) (bool, error) {
 	// "parse" the input arn into sections
 	arnSections, err := parse(arn)
 	if err != nil {
-		return false, fmt.Errorf("Could not parse input arn: %v", err)
+		return false, fmt.Errorf("could not parse input arn: %v", err)
 	}
 	patternSections, err := parse(pattern)
 	if err != nil {
-		return false, fmt.Errorf("Could not parse ArnLike string: %v", err)
+		return false, fmt.Errorf("could not parse ArnLike string: %v", err)
 	}
 
 	// Tidy regexp special characters. Escape the ones not used in ArnLike.
@@ -44,7 +45,7 @@ func ArnLike(arn, pattern string) (bool, error) {
 	for index := range arnSections {
 		patternGlob, err := regexp.Compile(patternSections[index])
 		if err != nil {
-			return false, fmt.Errorf("Could not parse %s: %v", patternSections[index], err)
+			return false, fmt.Errorf("could not parse %s: %v", patternSections[index], err)
 		}
 
 		if !patternGlob.MatchString(arnSections[index]) {
@@ -58,11 +59,11 @@ func ArnLike(arn, pattern string) (bool, error) {
 // parse is a copy of arn.Parse from the AWS SDK but represents the ARN as []string
 func parse(input string) ([]string, error) {
 	if !strings.HasPrefix(input, arnPrefix) {
-		return nil, fmt.Errorf(invalidPrefix)
+		return nil, errors.New(invalidPrefix)
 	}
 	arnSections := strings.SplitN(input, arnDelimiter, arnSectionsExpected)
 	if len(arnSections) != arnSectionsExpected {
-		return nil, fmt.Errorf(invalidSections)
+		return nil, errors.New(invalidSections)
 	}
 
 	return arnSections, nil
diff --git a/pkg/config/certs/certs.go b/pkg/config/certs/certs.go
index dc7b9d51..a3c8b557 100644
--- a/pkg/config/certs/certs.go
+++ b/pkg/config/certs/certs.go
@@ -101,7 +101,12 @@ func dumpPEM(filename string, mode os.FileMode, blockType string, bytes []byte)
 	if err != nil {
 		return err
 	}
-	defer f.Close()
+	defer func() {
+		if err := f.Close(); err != nil {
+			logrus.WithError(err).Warn("error closing file")
+		}
+	}()
+
 	return pem.Encode(f, &pem.Block{Type: blockType, Bytes: bytes})
 }
 
diff --git a/pkg/config/constants.go b/pkg/config/constants.go
index fb116809..d5c3bfa9 100644
--- a/pkg/config/constants.go
+++ b/pkg/config/constants.go
@@ -19,14 +19,6 @@ package config
 import "time"
 
 const (
-	// certFilename is the filename (under the StateDir) where the self-signed
-	// CA certificate will be stored.
-	certFilename = "cert.pem"
-
-	// keyFilename is the filename (under the StateDir) where the private key
-	// will be stored.
-	keyFilename = "key.pem"
-
 	// certLifetime is the lifetime of the CA certificate (100 years)
 	certLifetime = time.Hour * 24 * 365 * 100
 )
diff --git a/pkg/config/kubeconfig/kubeconfig.go b/pkg/config/kubeconfig/kubeconfig.go
index 2fb7a8ef..2a499162 100644
--- a/pkg/config/kubeconfig/kubeconfig.go
+++ b/pkg/config/kubeconfig/kubeconfig.go
@@ -47,7 +47,11 @@ func (p KubeconfigParams) WriteKubeconfig(outputPath string, t *template.Templat
 	if err != nil {
 		return err
 	}
-	defer f.Close()
+	defer func() {
+		if err := f.Close(); err != nil {
+			logrus.WithError(err).Warn("error closing file")
+		}
+	}()
 	return t.Execute(f, p)
 }
 
diff --git a/pkg/config/mapper.go b/pkg/config/mapper.go
index 0c33ab1f..5eaa1813 100644
--- a/pkg/config/mapper.go
+++ b/pkg/config/mapper.go
@@ -33,9 +33,9 @@ func (m *RoleMapping) Validate() error {
 	}
 
 	if m.RoleARN == "" && m.SSO == nil {
-		return fmt.Errorf("One of rolearn or SSO must be supplied")
+		return fmt.Errorf("one of rolearn or SSO must be supplied")
 	} else if m.RoleARN != "" && m.SSO != nil {
-		return fmt.Errorf("Only one of rolearn or SSO can be supplied")
+		return fmt.Errorf("only one of rolearn or SSO can be supplied")
 	}
 
 	if m.SSO != nil {
@@ -56,7 +56,7 @@ func (m *RoleMapping) Validate() error {
 		case "":
 			// treated as "aws"
 		default:
-			return fmt.Errorf("Partition '%s' is not a valid AWS partition", m.SSO.Partition)
+			return fmt.Errorf("partition '%s' is not a valid AWS partition", m.SSO.Partition)
 		}
 
 		ssoArnLikeString := m.SSOArnLike()
@@ -75,7 +75,7 @@ func (m *RoleMapping) Validate() error {
 // this RoleMapping
 func (m *RoleMapping) Matches(subject string) bool {
 	if m.RoleARN != "" {
-		return strings.ToLower(m.RoleARN) == strings.ToLower(subject)
+		return strings.EqualFold(m.RoleARN, subject)
 	}
 
 	// Assume the caller has called Validate(), which parses m.RoleARNLike
@@ -117,7 +117,7 @@ func (m *UserMapping) Validate() error {
 	}
 
 	if m.UserARN == "" {
-		return fmt.Errorf("Value for userarn must be supplied")
+		return fmt.Errorf("value for userarn must be supplied")
 	}
 
 	return nil
@@ -125,7 +125,7 @@ func (m *UserMapping) Validate() error {
 
 // Matches returns true if the supplied ARN string matche this UserMapping
 func (m *UserMapping) Matches(subject string) bool {
-	return strings.ToLower(m.UserARN) == strings.ToLower(subject)
+	return strings.EqualFold(m.UserARN, subject)
 }
 
 // Key returns UserARN.
diff --git a/pkg/ec2provider/ec2provider.go b/pkg/ec2provider/ec2provider.go
index 4d697d06..23a77076 100644
--- a/pkg/ec2provider/ec2provider.go
+++ b/pkg/ec2provider/ec2provider.go
@@ -66,17 +66,17 @@ type ec2Requests struct {
 
 type ec2ProviderImpl struct {
 	ec2                EC2API
-	privateDNSCache    ec2PrivateDNSCache
-	ec2Requests        ec2Requests
+	privateDNSCache    *ec2PrivateDNSCache
+	ec2Requests        *ec2Requests
 	instanceIdsChannel chan string
 }
 
 func New(ctx context.Context, roleARN, sourceARN, region string, qps int, burst int) EC2Provider {
-	dnsCache := ec2PrivateDNSCache{
+	dnsCache := &ec2PrivateDNSCache{
 		cache: make(map[string]string),
 		lock:  sync.RWMutex{},
 	}
-	ec2Requests := ec2Requests{
+	ec2Requests := &ec2Requests{
 		set:  make(map[string]bool),
 		lock: sync.RWMutex{},
 	}
diff --git a/pkg/endpoints/partitions.go b/pkg/endpoints/partitions.go
index 21054a95..a86f8b05 100644
--- a/pkg/endpoints/partitions.go
+++ b/pkg/endpoints/partitions.go
@@ -50,7 +50,7 @@ func GetSTSPartitionDomain(partition string) (string, error) {
 	case AwsIsoFPartitionID:
 		domain = "csp.hci.ic.gov"
 	default:
-		return "", fmt.Errorf("Partition %s not valid", partition)
+		return "", fmt.Errorf("partition %s not valid", partition)
 	}
 
 	return domain, nil
diff --git a/pkg/errutil/errors.go b/pkg/errutil/errors.go
index f777566e..a42e44ae 100644
--- a/pkg/errutil/errors.go
+++ b/pkg/errutil/errors.go
@@ -4,6 +4,6 @@ import (
 	"errors"
 )
 
-var ErrNotMapped = errors.New("Identity is not mapped")
+var ErrNotMapped = errors.New("identity is not mapped")
 
 var ErrIDAndARNMismatch = errors.New("ARN does not match User ID")
diff --git a/pkg/filecache/filecache.go b/pkg/filecache/filecache.go
index 5c2c4567..65961a07 100644
--- a/pkg/filecache/filecache.go
+++ b/pkg/filecache/filecache.go
@@ -171,7 +171,12 @@ func NewFileCacheProvider(clusterID, profile, roleARN string, provider aws.Crede
 
 		// do file locking on cache to prevent inconsistent reads
 		lock := resp.filelockCreator(resp.filename)
-		defer lock.Unlock()
+		defer func() {
+			if err := lock.Unlock(); err != nil {
+				logrus.WithError(err).Warn("error unlocking cache file")
+			}
+		}()
+
 		// wait up to a second for the file to lock
 		ctx, cancel := context.WithTimeout(context.TODO(), time.Second)
 		defer cancel()
@@ -220,11 +225,20 @@ func (f *FileCacheProvider) Retrieve(ctx context.Context) (aws.Credentials, erro
 
 			// do file locking on cache to prevent inconsistent writes
 			lock := f.filelockCreator(f.filename)
-			defer lock.Unlock()
+			defer func() {
+				if err := lock.Unlock(); err != nil {
+					logrus.WithError(err).Warn("error unlocking cache file")
+				}
+			}()
 			// wait up to a second for the file to lock
 			ctx, cancel := context.WithTimeout(ctx, time.Second)
 			defer cancel()
 			ok, err := lock.TryLockContext(ctx, 250*time.Millisecond) // try to lock every 1/4 second
+			if err != nil {
+				// can't get a lock, but still return the credential
+				logrus.Warnf("Unable to lock file %s: %v", f.filename, err)
+				return credential, nil
+			}
 			if !ok {
 				// can't get write lock to create/update cache, but still return the credential
 				logrus.Warnf("Unable to write lock file %s: %v", f.filename, err)
@@ -238,7 +252,6 @@ func (f *FileCacheProvider) Retrieve(ctx context.Context) (aws.Credentials, erro
 			if err != nil {
 				// can't write cache, but still return the credential
 				logrus.Warnf("Unable to update credential cache %s: %v", f.filename, err)
-				err = nil
 			} else {
 				logrus.Debug("Updated cached credential")
 			}
diff --git a/pkg/fileutil/util.go b/pkg/fileutil/util.go
index f7a57fa7..09c5abd7 100644
--- a/pkg/fileutil/util.go
+++ b/pkg/fileutil/util.go
@@ -55,7 +55,11 @@ func StartLoadDynamicFile(filename string, callBack FileChangeCallBack, stopCh <
 			metrics.Get().DynamicFileFailures.Inc()
 			return
 		}
-		defer watcher.Close()
+		defer func() {
+			if err := watcher.Close(); err != nil {
+				logrus.WithError(err).Warn("error closing file watcher")
+			}
+		}()
 		content, err := loadDynamicFile(filename, stopCh)
 		if err != nil {
 			logrus.Errorf("startLoadDynamicFile: failed when loading file %s, %v", filename, err)
diff --git a/pkg/mapper/configmap/configmap.go b/pkg/mapper/configmap/configmap.go
index f6627593..e7814668 100644
--- a/pkg/mapper/configmap/configmap.go
+++ b/pkg/mapper/configmap/configmap.go
@@ -241,11 +241,11 @@ func (ms *MapStore) saveMap(
 	}
 }
 
-// UserNotFound is the error returned when the user is not found in the config map.
-var UserNotFound = errors.New("User not found in configmap")
+// ErrUserNotFound is the error returned when the user is not found in the config map.
+var ErrUserNotFound = errors.New("user not found in configmap")
 
-// RoleNotFound is the error returned when the role is not found in the config map.
-var RoleNotFound = errors.New("Role not found in configmap")
+// ErrRoleNotFound is the error returned when the role is not found in the config map.
+var ErrRoleNotFound = errors.New("role not found in configmap")
 
 func (ms *MapStore) UserMapping(arn string) (config.UserMapping, error) {
 	ms.mutex.RLock()
@@ -255,7 +255,7 @@ func (ms *MapStore) UserMapping(arn string) (config.UserMapping, error) {
 			return user, nil
 		}
 	}
-	return config.UserMapping{}, UserNotFound
+	return config.UserMapping{}, ErrUserNotFound
 }
 
 func (ms *MapStore) RoleMapping(arn string) (config.RoleMapping, error) {
@@ -266,7 +266,7 @@ func (ms *MapStore) RoleMapping(arn string) (config.RoleMapping, error) {
 			return role, nil
 		}
 	}
-	return config.RoleMapping{}, RoleNotFound
+	return config.RoleMapping{}, ErrRoleNotFound
 }
 
 func (ms *MapStore) AWSAccount(id string) bool {
diff --git a/pkg/mapper/crd/controller/controller.go b/pkg/mapper/crd/controller/controller.go
index c3510302..ec726930 100644
--- a/pkg/mapper/crd/controller/controller.go
+++ b/pkg/mapper/crd/controller/controller.go
@@ -67,7 +67,7 @@ type Controller struct {
 	iamMappingsIndex cache.Indexer
 
 	// workqueue implements a FIFO queue used for processing items
-	workqueue workqueue.RateLimitingInterface
+	workqueue workqueue.TypedRateLimitingInterface[any]
 	// recorder implements the Event recorder interface for logging events.
 	recorder record.EventRecorder
 }
@@ -93,7 +93,7 @@ func New(
 		iamclientset:      iamclientset,
 		iamMappingLister:  iamMappingInformer.Lister(),
 		iamMappingsSynced: iamMappingInformer.Informer().HasSynced,
-		workqueue:         workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "IAMIdentityMappings"),
+		workqueue:         workqueue.NewNamedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[any](), "IAMIdentityMappings"),
 		recorder:          recorder,
 	}
 
@@ -102,12 +102,14 @@ func New(
 	// canonical ARNs, we're ignoring deletes because all checks for roles happen
 	// using the in-memory cache which is updated automatically on deletes no further
 	// actions are necessary
-	iamMappingInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
+	if _, err := iamMappingInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
 		AddFunc: controller.enqueueIAMIdentityMapping,
 		UpdateFunc: func(old, new interface{}) {
 			controller.enqueueIAMIdentityMapping(new)
 		},
-	})
+	}); err != nil {
+		logrus.WithError(err).Fatal("error adding event handler")
+	}
 
 	err := iamMappingInformer.Informer().GetIndexer().AddIndexers(cache.Indexers{
 		"canonicalARN": IndexIAMIdentityMappingByCanonicalArn,
diff --git a/pkg/mapper/crd/generated/clientset/versioned/fake/clientset_generated.go b/pkg/mapper/crd/generated/clientset/versioned/fake/clientset_generated.go
index 21af6827..504c5b46 100644
--- a/pkg/mapper/crd/generated/clientset/versioned/fake/clientset_generated.go
+++ b/pkg/mapper/crd/generated/clientset/versioned/fake/clientset_generated.go
@@ -18,6 +18,7 @@ limitations under the License.
 package fake
 
 import (
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/watch"
 	"k8s.io/client-go/discovery"
@@ -48,9 +49,13 @@ func NewSimpleClientset(objects ...runtime.Object) *Clientset {
 	cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
 	cs.AddReactor("*", "*", testing.ObjectReaction(o))
 	cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
+		var opts metav1.ListOptions
+		if watchActcion, ok := action.(testing.WatchActionImpl); ok {
+			opts = watchActcion.ListOptions
+		}
 		gvr := action.GetResource()
 		ns := action.GetNamespace()
-		watch, err := o.Watch(gvr, ns)
+		watch, err := o.Watch(gvr, ns, opts)
 		if err != nil {
 			return false, nil, err
 		}
diff --git a/pkg/mapper/crd/generated/clientset/versioned/typed/iamauthenticator/v1alpha1/iamauthenticator_client.go b/pkg/mapper/crd/generated/clientset/versioned/typed/iamauthenticator/v1alpha1/iamauthenticator_client.go
index 9beda553..dfaeece8 100644
--- a/pkg/mapper/crd/generated/clientset/versioned/typed/iamauthenticator/v1alpha1/iamauthenticator_client.go
+++ b/pkg/mapper/crd/generated/clientset/versioned/typed/iamauthenticator/v1alpha1/iamauthenticator_client.go
@@ -44,9 +44,7 @@ func (c *IamauthenticatorV1alpha1Client) IAMIdentityMappings() IAMIdentityMappin
 // where httpClient was generated with rest.HTTPClientFor(c).
 func NewForConfig(c *rest.Config) (*IamauthenticatorV1alpha1Client, error) {
 	config := *c
-	if err := setConfigDefaults(&config); err != nil {
-		return nil, err
-	}
+	setConfigDefaults(&config)
 	httpClient, err := rest.HTTPClientFor(&config)
 	if err != nil {
 		return nil, err
@@ -58,9 +56,7 @@ func NewForConfig(c *rest.Config) (*IamauthenticatorV1alpha1Client, error) {
 // Note the http client provided takes precedence over the configured transport values.
 func NewForConfigAndClient(c *rest.Config, h *http.Client) (*IamauthenticatorV1alpha1Client, error) {
 	config := *c
-	if err := setConfigDefaults(&config); err != nil {
-		return nil, err
-	}
+	setConfigDefaults(&config)
 	client, err := rest.RESTClientForConfigAndClient(&config, h)
 	if err != nil {
 		return nil, err
@@ -83,7 +79,7 @@ func New(c rest.Interface) *IamauthenticatorV1alpha1Client {
 	return &IamauthenticatorV1alpha1Client{c}
 }
 
-func setConfigDefaults(config *rest.Config) error {
+func setConfigDefaults(config *rest.Config) {
 	gv := iamauthenticatorv1alpha1.SchemeGroupVersion
 	config.GroupVersion = &gv
 	config.APIPath = "/apis"
@@ -92,8 +88,6 @@ func setConfigDefaults(config *rest.Config) error {
 	if config.UserAgent == "" {
 		config.UserAgent = rest.DefaultKubernetesUserAgent()
 	}
-
-	return nil
 }
 
 // RESTClient returns a RESTClient that is used to communicate
diff --git a/pkg/mapper/crd/generated/informers/externalversions/iamauthenticator/v1alpha1/iamidentitymapping.go b/pkg/mapper/crd/generated/informers/externalversions/iamauthenticator/v1alpha1/iamidentitymapping.go
index e09fb096..af1390b2 100644
--- a/pkg/mapper/crd/generated/informers/externalversions/iamauthenticator/v1alpha1/iamidentitymapping.go
+++ b/pkg/mapper/crd/generated/informers/externalversions/iamauthenticator/v1alpha1/iamidentitymapping.go
@@ -60,13 +60,25 @@ func NewFilteredIAMIdentityMappingInformer(client versioned.Interface, resyncPer
 				if tweakListOptions != nil {
 					tweakListOptions(&options)
 				}
-				return client.IamauthenticatorV1alpha1().IAMIdentityMappings().List(context.TODO(), options)
+				return client.IamauthenticatorV1alpha1().IAMIdentityMappings().List(context.Background(), options)
 			},
 			WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
 				if tweakListOptions != nil {
 					tweakListOptions(&options)
 				}
-				return client.IamauthenticatorV1alpha1().IAMIdentityMappings().Watch(context.TODO(), options)
+				return client.IamauthenticatorV1alpha1().IAMIdentityMappings().Watch(context.Background(), options)
+			},
+			ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) {
+				if tweakListOptions != nil {
+					tweakListOptions(&options)
+				}
+				return client.IamauthenticatorV1alpha1().IAMIdentityMappings().List(ctx, options)
+			},
+			WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) {
+				if tweakListOptions != nil {
+					tweakListOptions(&options)
+				}
+				return client.IamauthenticatorV1alpha1().IAMIdentityMappings().Watch(ctx, options)
 			},
 		},
 		&apisiamauthenticatorv1alpha1.IAMIdentityMapping{},
diff --git a/pkg/mapper/crd/mapper.go b/pkg/mapper/crd/mapper.go
index 6eaef399..f7e66cc5 100644
--- a/pkg/mapper/crd/mapper.go
+++ b/pkg/mapper/crd/mapper.go
@@ -81,7 +81,7 @@ func (m *CRDMapper) Start(stopCh <-chan struct{}) error {
 	m.iamInformerFactory.Start(stopCh)
 	go func() {
 		// Run starts worker goroutines and blocks
-		if err := m.Controller.Run(2, stopCh); err != nil {
+		if err := m.Run(2, stopCh); err != nil {
 			panic(err)
 		}
 	}()
diff --git a/pkg/mapper/dynamicfile/dynamicfile.go b/pkg/mapper/dynamicfile/dynamicfile.go
index 735cd3fb..fa97466c 100644
--- a/pkg/mapper/dynamicfile/dynamicfile.go
+++ b/pkg/mapper/dynamicfile/dynamicfile.go
@@ -125,7 +125,7 @@ func (ms *DynamicFileMapStore) LogMapping() {
 	for _, role := range ms.roles {
 		logrus.Info(role)
 	}
-	for awsAccount, _ := range ms.awsAccounts {
+	for awsAccount := range ms.awsAccounts {
 		logrus.Info(awsAccount)
 	}
 }
@@ -147,7 +147,7 @@ func (ms *DynamicFileMapStore) CallBackForFileLoad(dynamicContent []byte) error
 			key = userMapping.UserId
 		}
 		if key == "" {
-			errs = append(errs, fmt.Errorf("Value for userarn or userid(if dynamicfileUserIDStrict = true) must be supplied"))
+			errs = append(errs, fmt.Errorf("value for userarn or userid(if dynamicfileUserIDStrict = true) must be supplied"))
 		} else {
 			userMappings = append(userMappings, userMapping)
 		}
@@ -159,7 +159,7 @@ func (ms *DynamicFileMapStore) CallBackForFileLoad(dynamicContent []byte) error
 			key = roleMapping.UserId
 		}
 		if key == "" {
-			errs = append(errs, fmt.Errorf("Value for rolearn or userid(if dynamicfileUserIDStrict = true) must be supplied"))
+			errs = append(errs, fmt.Errorf("value for rolearn or userid(if dynamicfileUserIDStrict = true) must be supplied"))
 		} else {
 			roleMappings = append(roleMappings, roleMapping)
 		}
diff --git a/pkg/server/server.go b/pkg/server/server.go
index f5d8a29c..a313cf83 100644
--- a/pkg/server/server.go
+++ b/pkg/server/server.go
@@ -25,7 +25,6 @@ import (
 	"net/http"
 	"regexp"
 	"strings"
-	"sync"
 	"time"
 
 	awsconfig "github.com/aws/aws-sdk-go-v2/config"
@@ -64,13 +63,12 @@ var tokenReviewDenyJSON = func() []byte {
 
 // Pattern to match EC2 instance IDs
 var (
-	instanceIDPattern = regexp.MustCompile("^i-(\\w{8}|\\w{17})$")
+	instanceIDPattern = regexp.MustCompile(`^i-(\w{8}|\w{17})$`)
 )
 
 // server state (internal)
 type handler struct {
 	http.ServeMux
-	mutex                     sync.RWMutex
 	verifier                  token.Verifier
 	ec2Provider               ec2provider.EC2Provider
 	clusterID                 string
@@ -141,7 +139,11 @@ func New(ctx context.Context, cfg config.Config) *Server {
 
 	// create a logrus logger for HTTP error logs
 	errLog := logrus.WithField("http", "error").Writer()
-	defer errLog.Close()
+	defer func() {
+		if err := errLog.Close(); err != nil {
+			logrus.WithError(err).Warn("error closing error log writer")
+		}
+	}()
 
 	logrus.Infof("listening on %s", listener.Addr())
 	logrus.Infof("reconfigure your apiserver with `--authentication-token-webhook-config-file=%s` to enable (assuming default hostPath mounts)", c.GenerateKubeconfigPath)
@@ -158,19 +160,22 @@ func New(ctx context.Context, cfg config.Config) *Server {
 // Run will run the server closing the connection if there is a struct on the channel
 func (c *Server) Run(stopCh <-chan struct{}) {
 
-	defer c.listener.Close()
+	defer func() {
+		if err := c.listener.Close(); err != nil {
+			logrus.WithError(err).Warn("error closing listener")
+		}
+	}()
 
 	go func() {
-		http.ListenAndServe(":21363", &healthzHandler{})
+		if err := http.ListenAndServe(":21363", &healthzHandler{}); err != nil {
+			logrus.WithError(err).Error("healthz server exited")
+		}
 	}()
 	go func() {
-		for {
-			select {
-			case <-stopCh:
-				logrus.Info("shut down mapper before return from Run")
-				close(c.internalHandler.backendMapper.mapperStopCh)
-				return
-			}
+		for range stopCh {
+			logrus.Info("shut down mapper before return from Run")
+			close(c.internalHandler.backendMapper.mapperStopCh)
+			return
 		}
 	}()
 	if err := c.httpServer.Serve(c.listener); err != nil {
@@ -179,18 +184,24 @@ func (c *Server) Run(stopCh <-chan struct{}) {
 }
 
 func (c *Server) Close() {
-	c.listener.Close()
+	if err := c.listener.Close(); err != nil {
+		logrus.WithError(err).Error("could not close listener")
+	}
 
 	ctxTimeout, cancel := context.WithTimeout(context.Background(), time.Second*5)
 	defer cancel()
 
-	c.httpServer.Shutdown(ctxTimeout)
+	if err := c.httpServer.Shutdown(ctxTimeout); err != nil {
+		logrus.WithError(err).Error("could not gracefully shutdown http server")
+	}
 }
 
 type healthzHandler struct{}
 
 func (m *healthzHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	fmt.Fprintf(w, "ok")
+	if _, err := fmt.Fprintf(w, "ok"); err != nil {
+		logrus.WithError(err).Error("could not write response")
+	}
 }
 func (c *Server) getHandler(ctx context.Context, backendMapper BackendMapper, ec2DescribeQps int, ec2DescribeBurst int) *handler {
 	stopCh := ctx.Done()
@@ -221,7 +232,7 @@ func (c *Server) getHandler(ctx context.Context, backendMapper BackendMapper, ec
 		ec2Provider:               ec2provider.New(ctx, c.ServerEC2DescribeInstancesRoleARN, c.SourceARN, instanceRegion, ec2DescribeQps, ec2DescribeBurst),
 		clusterID:                 c.ClusterID,
 		backendMapper:             backendMapper,
-		scrubbedAccounts:          c.Config.ScrubbedAWSAccounts,
+		scrubbedAccounts:          c.ScrubbedAWSAccounts,
 		cfg:                       c.Config,
 		backendModeConfigInitDone: false,
 	}
@@ -231,7 +242,9 @@ func (c *Server) getHandler(ctx context.Context, backendMapper BackendMapper, ec
 	})
 	h.Handle("/metrics", promhttp.Handler())
 	h.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
-		fmt.Fprintf(w, "ok")
+		if _, err := fmt.Fprintf(w, "ok"); err != nil {
+			logrus.WithError(err).Error("could not write response")
+		}
 	})
 	logrus.Infof("Starting the h.ec2Provider.startEc2DescribeBatchProcessing ")
 	go h.ec2Provider.StartEc2DescribeBatchProcessing(ctx)
@@ -249,7 +262,7 @@ func BuildMapperChain(cfg config.Config, modes []string) (BackendMapper, error)
 	}
 	for _, mode := range modes {
 		switch mode {
-		case mapper.ModeFile:
+		case mapper.ModeFile: //nolint:all
 			fallthrough
 		case mapper.ModeMountedFile:
 			fileMapper, err := file.NewFileMapper(cfg)
@@ -257,7 +270,7 @@ func BuildMapperChain(cfg config.Config, modes []string) (BackendMapper, error)
 				return BackendMapper{}, fmt.Errorf("backend-mode %q creation failed: %v", mode, err)
 			}
 			backendMapper.mappers = append(backendMapper.mappers, fileMapper)
-		case mapper.ModeConfigMap:
+		case mapper.ModeConfigMap: //nolint:all
 			fallthrough
 		case mapper.ModeEKSConfigMap:
 			configMapMapper, err := configmap.NewConfigMapMapper(cfg)
@@ -328,7 +341,11 @@ func (h *handler) authenticateEndpoint(ctx context.Context, w http.ResponseWrite
 		metrics.Get().Latency.WithLabelValues(metrics.Malformed).Observe(duration(start))
 		return
 	}
-	defer req.Body.Close()
+	defer func() {
+		if err := req.Body.Close(); err != nil {
+			log.WithError(err).Warn("error closing request body")
+		}
+	}()
 
 	var tokenReview authenticationv1beta1.TokenReview
 	if err := json.NewDecoder(req.Body).Decode(&tokenReview); err != nil {
@@ -350,7 +367,9 @@ func (h *handler) authenticateEndpoint(ctx context.Context, w http.ResponseWrite
 			metrics.Get().Latency.WithLabelValues(metrics.STSThrottling).Observe(duration(start))
 			log.WithError(err).Warn("access denied")
 			w.WriteHeader(http.StatusTooManyRequests)
-			w.Write(tokenReviewDenyJSON)
+			if _, err := w.Write(tokenReviewDenyJSON); err != nil {
+				log.WithError(err).Error("could not write response")
+			}
 			return
 		} else if _, ok := err.(token.STSError); ok {
 			metrics.Get().Latency.WithLabelValues(metrics.STSError).Observe(duration(start))
@@ -359,7 +378,9 @@ func (h *handler) authenticateEndpoint(ctx context.Context, w http.ResponseWrite
 		}
 		log.WithError(err).Warn("access denied")
 		w.WriteHeader(http.StatusForbidden)
-		w.Write(tokenReviewDenyJSON)
+		if _, err := w.Write(tokenReviewDenyJSON); err != nil {
+			log.WithError(err).Error("could not write response")
+		}
 		return
 	}
 
@@ -382,7 +403,9 @@ func (h *handler) authenticateEndpoint(ctx context.Context, w http.ResponseWrite
 		metrics.Get().Latency.WithLabelValues(metrics.Unknown).Observe(duration(start))
 		log.WithError(err).Warn("access denied")
 		w.WriteHeader(http.StatusForbidden)
-		w.Write(tokenReviewDenyJSON)
+		if _, err := w.Write(tokenReviewDenyJSON); err != nil {
+			log.WithError(err).Error("could not write response")
+		}
 		return
 	}
 
@@ -412,7 +435,7 @@ func (h *handler) authenticateEndpoint(ctx context.Context, w http.ResponseWrite
 		userExtra["sigs.k8s.io/aws-iam-authenticator/principalId"] = authenticationv1beta1.ExtraValue{identity.UserID}
 	}
 
-	json.NewEncoder(w).Encode(authenticationv1beta1.TokenReview{
+	if err := json.NewEncoder(w).Encode(authenticationv1beta1.TokenReview{
 		Status: authenticationv1beta1.TokenReviewStatus{
 			Authenticated: true,
 			User: authenticationv1beta1.UserInfo{
@@ -422,7 +445,9 @@ func (h *handler) authenticateEndpoint(ctx context.Context, w http.ResponseWrite
 				Extra:    userExtra,
 			},
 		},
-	})
+	}); err != nil {
+		log.WithError(err).Error("could not serialize response")
+	}
 }
 
 func ReservedPrefixExists(username string, reservedList []string) bool {
@@ -498,14 +523,14 @@ func (h *handler) renderTemplate(ctx context.Context, template string, identity
 		if err != nil {
 			return "", err
 		}
-		template = strings.Replace(template, "{{EC2PrivateDNSName}}", privateDNSName, -1)
+		template = strings.ReplaceAll(template, "{{EC2PrivateDNSName}}", privateDNSName)
 	}
 
-	template = strings.Replace(template, "{{AccountID}}", identity.AccountID, -1)
-	sessionName := strings.Replace(identity.SessionName, "@", "-", -1)
-	template = strings.Replace(template, "{{SessionName}}", sessionName, -1)
-	template = strings.Replace(template, "{{SessionNameRaw}}", identity.SessionName, -1)
-	template = strings.Replace(template, "{{AccessKeyID}}", identity.AccessKeyID, -1)
+	template = strings.ReplaceAll(template, "{{AccountID}}", identity.AccountID)
+	sessionName := strings.ReplaceAll(identity.SessionName, "@", "-")
+	template = strings.ReplaceAll(template, "{{SessionName}}", sessionName)
+	template = strings.ReplaceAll(template, "{{SessionNameRaw}}", identity.SessionName)
+	template = strings.ReplaceAll(template, "{{AccessKeyID}}", identity.AccessKeyID)
 
 	return template, nil
 }
diff --git a/pkg/token/token.go b/pkg/token/token.go
index b5203b46..44aec24d 100644
--- a/pkg/token/token.go
+++ b/pkg/token/token.go
@@ -34,7 +34,7 @@ import (
 
 	"github.com/aws/aws-sdk-go-v2/aws"
 	"github.com/aws/aws-sdk-go-v2/aws/middleware"
-	"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
+	v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
 	"github.com/aws/aws-sdk-go-v2/config"
 	"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
 	"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
@@ -681,7 +681,10 @@ func (v *tokenVerifier) Verify(token string) (*Identity, error) {
 		return nil, FormatError{fmt.Sprintf("X-Amz-Date parameter is expired (%.f minute expiration) %s", presignedURLExpiration.Minutes(), dateParam)}
 	}
 
-	req, err := http.NewRequest("GET", parsedURL.String(), nil)
+	req, err := http.NewRequest(http.MethodGet, parsedURL.String(), nil)
+	if err != nil {
+		return nil, FormatError{fmt.Sprintf("error creating HTTP request: %s", err.Error())}
+	}
 	req.Header.Set(clusterIDHeader, v.clusterID)
 	req.Header.Set("accept", "application/json")
 
@@ -694,7 +697,11 @@ func (v *tokenVerifier) Verify(token string) (*Identity, error) {
 		}
 		return nil, NewSTSError(fmt.Sprintf("error during GET: %v on %s endpoint", err, stsRegion))
 	}
-	defer response.Body.Close()
+	defer func() {
+		if err := response.Body.Close(); err != nil {
+			logrus.WithError(err).Warn("error closing response body	")
+		}
+	}()
 
 	responseBody, err := io.ReadAll(response.Body)
 	if err != nil {
@@ -763,7 +770,7 @@ func getIdentityFromSTSResponse(id *Identity, wrapper getCallerIdentityWrapper)
 
 func validateDuplicateParameters(queryParams url.Values) error {
 	duplicateCheck := make(map[string]bool)
-	for key, _ := range queryParams {
+	for key := range queryParams {
 		if _, found := duplicateCheck[strings.ToLower(key)]; found {
 			return FormatError{fmt.Sprintf("duplicate query parameter found: %q", key)}
 		}
@@ -775,7 +782,7 @@ func validateDuplicateParameters(queryParams url.Values) error {
 func hasSignedClusterIDHeader(paramsLower *url.Values) bool {
 	signedHeaders := strings.Split(paramsLower.Get("x-amz-signedheaders"), ";")
 	for _, hdr := range signedHeaders {
-		if strings.ToLower(hdr) == strings.ToLower(clusterIDHeader) {
+		if strings.EqualFold(hdr, clusterIDHeader) {
 			return true
 		}
 	}



Test patch:
diff --git a/pkg/arn/arn_test.go b/pkg/arn/arn_test.go
index fcec2814..de4e0010 100644
--- a/pkg/arn/arn_test.go
+++ b/pkg/arn/arn_test.go
@@ -10,7 +10,7 @@ var arnTests = []struct {
 	expected string // canonacalized arn
 	err      error  // expected error value
 }{
-	{"NOT AN ARN", "", fmt.Errorf("Not an arn")},
+	{"NOT AN ARN", "", fmt.Errorf("not an arn")},
 	{"arn:aws:iam::123456789012:user/Alice", "arn:aws:iam::123456789012:user/Alice", nil},
 	{"arn:aws:iam::123456789012:role/Users", "arn:aws:iam::123456789012:role/Users", nil},
 	{"arn:aws:sts::123456789012:assumed-role/Admin/Session", "arn:aws:iam::123456789012:role/Admin", nil},
@@ -39,7 +39,7 @@ var arnStripTests = []struct {
 	expected string // canonacalized arn
 	err      error  // expected error value
 }{
-	{"NOT AN ARN", "", fmt.Errorf("Not an arn")},
+	{"NOT AN ARN", "", fmt.Errorf("not an arn")},
 	{"arn:aws:iam::123456789012:role/Org/Team/Admin", "arn:aws:iam::123456789012:role/Admin", nil},
 	{"arn:aws:iam::123456789012:role/Admin", "arn:aws:iam::123456789012:role/Admin", nil},
 	{"arn:aws:iam::123456789012:user/Alice", "arn:aws:iam::123456789012:user/Alice", nil},
diff --git a/pkg/ec2provider/ec2provider_test.go b/pkg/ec2provider/ec2provider_test.go
index a27f78c9..df6d1af5 100644
--- a/pkg/ec2provider/ec2provider_test.go
+++ b/pkg/ec2provider/ec2provider_test.go
@@ -49,11 +49,11 @@ func (c *mockEc2Client) DescribeInstances(ctx context.Context, in *ec2.DescribeI
 }
 
 func newMockedEC2ProviderImpl() *ec2ProviderImpl {
-	dnsCache := ec2PrivateDNSCache{
+	dnsCache := &ec2PrivateDNSCache{
 		cache: make(map[string]string),
 		lock:  sync.RWMutex{},
 	}
-	ec2Requests := ec2Requests{
+	ec2Requests := &ec2Requests{
 		set:  make(map[string]bool),
 		lock: sync.RWMutex{},
 	}
diff --git a/pkg/filecache/filecache_test.go b/pkg/filecache/filecache_test.go
index 244e3b8d..3a6d4d13 100644
--- a/pkg/filecache/filecache_test.go
+++ b/pkg/filecache/filecache_test.go
@@ -143,12 +143,18 @@ func validateFileCacheProvider(t *testing.T, p *FileCacheProvider, err error, c
 func testSetEnv(t *testing.T, key, value string) func() {
 	t.Helper()
 	old := os.Getenv(key)
-	os.Setenv(key, value)
+	if err := os.Setenv(key, value); err != nil {
+		t.Fatalf("Failed to set env var %s: %v", key, err)
+	}
 	return func() {
 		if old == "" {
-			os.Unsetenv(key)
+			if err := os.Unsetenv(key); err != nil {
+				t.Fatalf("Failed to unset env var %s: %v", key, err)
+			}
 		} else {
-			os.Setenv(key, old)
+			if err := os.Setenv(key, old); err != nil {
+				t.Fatalf("Failed to set env var %s: %v", key, err)
+			}
 		}
 	}
 }
@@ -220,7 +226,9 @@ func TestNewFileCacheProvider_Unlockable(t *testing.T) {
 	provider := &stubProvider{}
 
 	tfs, tfl := getMocks()
-	tfs.Create(testFilename)
+	if _, err := tfs.Create(testFilename); err != nil {
+		t.Fatalf("Failed to create test file: %v", err)
+	}
 
 	// unable to lock
 	tfl.success = false
@@ -242,7 +250,9 @@ func TestNewFileCacheProvider_Unreadable(t *testing.T) {
 	provider := &stubProvider{}
 
 	tfs, tfl := getMocks()
-	tfs.Create(testFilename)
+	if _, err := tfs.Create(testFilename); err != nil {
+		t.Fatalf("Failed to create test file: %v", err)
+	}
 	tfl.err = fmt.Errorf("open %s: permission denied", testFilename)
 	tfl.success = false
 
@@ -267,17 +277,21 @@ func TestNewFileCacheProvider_Unparseable(t *testing.T) {
 	provider := &stubProvider{}
 
 	tfs, tfl := getMocks()
-	tfs.Create(testFilename)
+	if _, err := tfs.Create(testFilename); err != nil {
+		t.Fatalf("Failed to create test file: %v", err)
+	}
 
 	_, err := NewFileCacheProvider("CLUSTER", "PROFILE", "ARN", provider,
 		WithFilename(testFilename),
 		WithFs(tfs),
 		WithFileLockerCreator(func(string) FileLocker {
-			afero.WriteFile(
+			if err := afero.WriteFile(
 				tfs,
 				testFilename,
 				[]byte("invalid: yaml: file"),
-				0700)
+				0700); err != nil {
+				t.Fatalf("Failed to write test file: %v", err)
+			}
 			return tfl
 		}),
 	)
@@ -300,7 +314,9 @@ func TestNewFileCacheProvider_Empty(t *testing.T) {
 		WithFilename(testFilename),
 		WithFs(tfs),
 		WithFileLockerCreator(func(string) FileLocker {
-			tfs.Create(testFilename)
+			if _, err := tfs.Create(testFilename); err != nil {
+				t.Fatalf("Failed to create test file: %v", err)
+			}
 			return tfl
 		}))
 	if err != nil {
@@ -317,22 +333,25 @@ func TestNewFileCacheProvider_ExistingCluster(t *testing.T) {
 	provider := &stubProvider{}
 
 	tfs, tfl := getMocks()
-	tfs.Create(testFilename)
+	if _, err := tfs.Create(testFilename); err != nil {
+		t.Fatalf("Failed to create test file: %v", err)
+	}
 
 	// successfully parse existing cluster without matching arn
 	p, err := NewFileCacheProvider("CLUSTER", "PROFILE", "ARN", provider,
 		WithFilename(testFilename),
 		WithFs(tfs),
 		WithFileLockerCreator(func(string) FileLocker {
-
-			afero.WriteFile(
+			if err := afero.WriteFile(
 				tfs,
 				testFilename,
 				[]byte(`clusters:
   CLUSTER:
     PROFILE2: {}
 `),
-				0700)
+				0700); err != nil {
+				t.Fatalf("Failed to write test file: %v", err)
+			}
 			return tfl
 		}),
 	)
@@ -357,15 +376,21 @@ func TestNewFileCacheProvider_ExistingARN(t *testing.T) {
         expires: ` + expiry.Format(time.RFC3339Nano) + `
 `)
 	tfs, tfl := getMocks()
-	tfs.Create(testFilename)
+	if _, err := tfs.Create(testFilename); err != nil {
+		t.Fatalf("Failed to create test file: %v", err)
+	}
 
 	// successfully parse cluster with matching arn
 	p, err := NewFileCacheProvider("CLUSTER", "PROFILE", "ARN", provider,
 		WithFilename(testFilename),
 		WithFs(tfs),
 		WithFileLockerCreator(func(string) FileLocker {
-			tfs.Create(testFilename)
-			afero.WriteFile(tfs, testFilename, content, 0700)
+			if _, err := tfs.Create(testFilename); err != nil {
+				t.Fatalf("Failed to create test file: %v", err)
+			}
+			if err := afero.WriteFile(tfs, testFilename, content, 0700); err != nil {
+				t.Fatalf("Failed to write test file: %v", err)
+			}
 			return tfl
 		}),
 	)
@@ -401,7 +426,9 @@ func TestFileCacheProvider_Retrieve_NoExpirer(t *testing.T) {
 		WithFilename(testFilename),
 		WithFs(tfs),
 		WithFileLockerCreator(func(string) FileLocker {
-			tfs.Create(testFilename)
+			if _, err := tfs.Create(testFilename); err != nil {
+				t.Fatalf("Failed to create test file: %v", err)
+			}
 			return tfl
 		}),
 	)
@@ -432,7 +459,9 @@ func TestFileCacheProvider_Retrieve_WithExpirer_Unlockable(t *testing.T) {
 		WithFilename(testFilename),
 		WithFs(tfs),
 		WithFileLockerCreator(func(string) FileLocker {
-			tfs.Create(testFilename)
+			if _, err := tfs.Create(testFilename); err != nil {
+				t.Fatalf("Failed to create test file: %v", err)
+			}
 			return tfl
 		}))
 	validateFileCacheProvider(t, p, err, provider)
@@ -465,7 +494,9 @@ func TestFileCacheProvider_Retrieve_WithExpirer_Unwritable(t *testing.T) {
 		WithFilename(testFilename),
 		WithFs(tfs),
 		WithFileLockerCreator(func(string) FileLocker {
-			tfs.Create(testFilename)
+			if _, err := tfs.Create(testFilename); err != nil {
+				t.Fatalf("Failed to create test file: %v", err)
+			}
 			return tfl
 		}),
 	)
@@ -516,7 +547,9 @@ func TestFileCacheProvider_Retrieve_WithExpirer_Writable(t *testing.T) {
 		WithFilename(testFilename),
 		WithFs(tfs),
 		WithFileLockerCreator(func(string) FileLocker {
-			tfs.Create(testFilename)
+			if _, err := tfs.Create(testFilename); err != nil {
+				t.Fatalf("Failed to create test file: %v", err)
+			}
 			return tfl
 		}),
 	)
@@ -542,7 +575,9 @@ func TestFileCacheProvider_Retrieve_CacheHit(t *testing.T) {
 	currentTime := time.Now()
 
 	tfs, tfl := getMocks()
-	tfs.Create(testFilename)
+	if _, err := tfs.Create(testFilename); err != nil {
+		t.Fatalf("Failed to create test file: %v", err)
+	}
 
 	// successfully parse cluster with matching arn
 	content := []byte(`clusters:
@@ -561,8 +596,12 @@ func TestFileCacheProvider_Retrieve_CacheHit(t *testing.T) {
 		WithFilename(testFilename),
 		WithFs(tfs),
 		WithFileLockerCreator(func(string) FileLocker {
-			tfs.Create(testFilename)
-			afero.WriteFile(tfs, testFilename, content, 0700)
+			if _, err := tfs.Create(testFilename); err != nil {
+				t.Fatalf("Failed to create test file: %v", err)
+			}
+			if err := afero.WriteFile(tfs, testFilename, content, 0700); err != nil {
+				t.Fatalf("Failed to write test file: %v", err)
+			}
 			return tfl
 		}))
 	validateFileCacheProvider(t, p, err, provider)
diff --git a/pkg/fileutil/util_test.go b/pkg/fileutil/util_test.go
index 44bf4cf4..7d31a42d 100644
--- a/pkg/fileutil/util_test.go
+++ b/pkg/fileutil/util_test.go
@@ -9,17 +9,10 @@ import (
 	"testing"
 	"time"
 
+	"github.com/sirupsen/logrus"
 	"k8s.io/apimachinery/pkg/util/wait"
 )
 
-var origFileContent = `
-Abbatxt7095
-`
-
-var updatedFileContent = `
-efgwht2033
-`
-
 type testStruct struct {
 	callCount       int
 	expectedContent string
@@ -72,7 +65,11 @@ func TestLoadDynamicFile(t *testing.T) {
 	if err != nil {
 		t.Errorf("failed to create a local temp file %v", err)
 	}
-	defer os.Remove(f.Name())
+	defer func() {
+		if err := os.Remove(f.Name()); err != nil {
+			logrus.WithError(err).Warn("error removing temp file")
+		}
+	}()
 
 	StartLoadDynamicFile(f.Name(), testA, stopCh)
 	defer close(stopCh)
@@ -133,7 +130,9 @@ func TestDeleteDynamicFile(t *testing.T) {
 	StartLoadDynamicFile("/tmp/delete.txt", testA, stopCh)
 	defer close(stopCh)
 	time.Sleep(2 * time.Second)
-	os.WriteFile("/tmp/delete.txt", []byte("test"), 0777)
+	if err := os.WriteFile("/tmp/delete.txt", []byte("test"), 0777); err != nil {
+		t.Errorf("failed to update a temp file %s, err: %v", "/tmp/delete.txt", err)
+	}
 	for {
 		time.Sleep(1 * time.Second)
 		testA.mutex.Lock()
@@ -144,7 +143,9 @@ func TestDeleteDynamicFile(t *testing.T) {
 		}
 		testA.mutex.Unlock()
 	}
-	os.Remove("/tmp/delete.txt")
+	if err := os.Remove("/tmp/delete.txt"); err != nil {
+		t.Errorf("failed to remove temp file %s, err: %v", "/tmp/delete.txt", err)
+	}
 	time.Sleep(2 * time.Second)
 	testA.mutex.Lock()
 	if testA.expectedContent != "" {
diff --git a/pkg/httputil/client_test.go b/pkg/httputil/client_test.go
index 2e31229d..232ebecd 100644
--- a/pkg/httputil/client_test.go
+++ b/pkg/httputil/client_test.go
@@ -127,8 +127,10 @@ func TestNewRateLimitedClient(t *testing.T) {
 func testHandler(w http.ResponseWriter, req *http.Request) {
 	switch req.Method {
 	case "GET":
-		fmt.Fprint(w, `test`)
+		if _, err := fmt.Fprint(w, `test`); err != nil {
+			http.Error(w, "Internal Server Error", 500)
+		}
 	default:
-		http.Error(w, "Method Not Allowed", 405)
+		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
 	}
 }
diff --git a/pkg/mapper/configmap/configmap_test.go b/pkg/mapper/configmap/configmap_test.go
index 9706907a..10c3a7a9 100644
--- a/pkg/mapper/configmap/configmap_test.go
+++ b/pkg/mapper/configmap/configmap_test.go
@@ -34,8 +34,8 @@ var (
 	}
 )
 
-func makeStore() MapStore {
-	ms := MapStore{
+func makeStore() *MapStore {
+	ms := &MapStore{
 		users:       make(map[string]config.UserMapping),
 		roles:       make(map[string]config.RoleMapping),
 		awsAccounts: make(map[string]interface{}),
@@ -47,11 +47,11 @@ func makeStore() MapStore {
 	return ms
 }
 
-func makeStoreWClient() (MapStore, *fakeConfigMaps) {
+func makeStoreWClient() (*MapStore, *fakeConfigMaps) {
 	fakeCore := &fake.FakeCoreV1{}
 	fakeCore.Fake = &k8stesting.Fake{}
 	fakeConfigMaps := newFakeConfigMaps(fakeCore, "")
-	ms := MapStore{
+	ms := &MapStore{
 		users:     make(map[string]config.UserMapping),
 		roles:     make(map[string]config.RoleMapping),
 		configMap: typedcorev1.ConfigMapInterface(fakeConfigMaps),
@@ -70,8 +70,8 @@ func TestUserMapping(t *testing.T) {
 	}
 
 	user, err = ms.UserMapping("nic")
-	if err != UserNotFound {
-		t.Errorf("UserNotFound error was not returned for user 'nic'")
+	if err != ErrUserNotFound {
+		t.Errorf("ErrUserNotFound error was not returned for user 'nic'")
 	}
 	if !reflect.DeepEqual(user, config.UserMapping{}) {
 		t.Errorf("User value returned when user is not in the map was not empty: %+v", user)
@@ -89,11 +89,11 @@ func TestRoleMapping(t *testing.T) {
 	}
 
 	role, err = ms.RoleMapping("borg")
-	if err != RoleNotFound {
-		t.Errorf("RoleNotFound error was not returend for role 'borg'")
+	if err != ErrRoleNotFound {
+		t.Errorf("ErrRoleNotFound error was not returend for role 'borg'")
 	}
 	if !reflect.DeepEqual(role, config.RoleMapping{}) {
-		t.Errorf("Role value returend when role is not in map was not empty: %+v", role)
+		t.Errorf("Role value returned when role is not in map was not empty: %+v", role)
 	}
 }
 
@@ -179,7 +179,7 @@ func TestLoadConfigMap(t *testing.T) {
 
 	watcher := watch.NewFake()
 
-	fakeConfigMaps.Fake.Fake.AddWatchReactor("configmaps",
+	fakeConfigMaps.Fake.AddWatchReactor("configmaps",
 		func(action k8stesting.Action) (handled bool, ret watch.Interface, err error) {
 			return true, watcher, nil
 		})
@@ -240,7 +240,7 @@ func TestLoadConfigMap(t *testing.T) {
 	}
 
 	expectedUser.Groups = append(expectedUser.Groups, "test")
-	user, err = ms.UserMapping("arn:aws:iam::012345678912:user/NIC")
+	user, _ = ms.UserMapping("arn:aws:iam::012345678912:user/NIC")
 	if !reflect.DeepEqual(user, expectedUser) {
 		t.Errorf("Updated returned from mapping does not match expected user. (Actual: %+v, Expected: %+v", user, expectedUser)
 	}
@@ -252,15 +252,14 @@ func TestLoadConfigMap(t *testing.T) {
 	}
 
 	user, err = ms.UserMapping("arn:iam:beswar")
-	if !reflect.DeepEqual(user, expectedUser) {
+	if err != nil || !reflect.DeepEqual(user, expectedUser) {
 		t.Errorf("Updated did not return new user 'arn:iam:beswar', matching expected value. (Actual: %+v, Expected: %+v", user, expectedUser)
 	}
 
-	user, err = ms.UserMapping("arn:iam:matlan")
-	if err != UserNotFound {
+	_, err = ms.UserMapping("arn:iam:matlan")
+	if err != ErrUserNotFound {
 		t.Errorf("Expected updated mapping not to contain user 'arn:iam:matlan', got err: %v", err)
 	}
-
 }
 
 func TestParseMap(t *testing.T) {
diff --git a/pkg/mapper/crd/controller/controller_test.go b/pkg/mapper/crd/controller/controller_test.go
index 8324a999..a4af561f 100644
--- a/pkg/mapper/crd/controller/controller_test.go
+++ b/pkg/mapper/crd/controller/controller_test.go
@@ -87,7 +87,7 @@ func (f *fixture) newController() (*Controller, informers.SharedInformerFactory)
 	c.recorder = &record.FakeRecorder{}
 
 	for _, f := range f.iamIdentityLister {
-		i.Iamauthenticator().V1alpha1().IAMIdentityMappings().Informer().GetIndexer().Add(f)
+		_ = i.Iamauthenticator().V1alpha1().IAMIdentityMappings().Informer().GetIndexer().Add(f)
 	}
 
 	return c, i
@@ -97,10 +97,6 @@ func (f *fixture) run(iamIdentityName string) {
 	f.runController(iamIdentityName, true, false)
 }
 
-func (f *fixture) runExpectError(iamIdentityName string) {
-	f.runController(iamIdentityName, true, true)
-}
-
 func (f *fixture) runController(iamIdentityName string, startInformers bool, expectError bool) {
 	c, i := f.newController()
 	if startInformers {
@@ -147,7 +143,7 @@ func (f *fixture) runController(iamIdentityName string, startInformers bool, exp
 }
 
 func checkAction(expected, actual core.Action, t *testing.T) {
-	if !(expected.Matches(actual.GetVerb(), actual.GetResource().Resource) && actual.GetSubresource() == expected.GetSubresource()) {
+	if !expected.Matches(actual.GetVerb(), actual.GetResource().Resource) || actual.GetSubresource() != expected.GetSubresource() {
 		t.Errorf("expected\n\t%#v\ngot\n\t%#v", expected, actual)
 		return
 	}
@@ -163,15 +159,6 @@ func checkAction(expected, actual core.Action, t *testing.T) {
 		expObject := e.GetObject()
 		object := a.GetObject()
 
-		if !reflect.DeepEqual(expObject, object) {
-			t.Errorf("action %s %s has wrong object\nDiff:\n %s",
-				a.GetVerb(), a.GetResource().Resource, diff.ObjectGoPrintSideBySide(expObject, object))
-		}
-	case core.UpdateAction:
-		e, _ := expected.(core.UpdateAction)
-		expObject := e.GetObject()
-		object := a.GetObject()
-
 		if !reflect.DeepEqual(expObject, object) {
 			t.Errorf("action %s %s has wrong object\nDiff:\n %s",
 				a.GetVerb(), a.GetResource().Resource, diff.ObjectGoPrintSideBySide(expObject, object))
@@ -202,21 +189,11 @@ func filterInformerActions(actions []core.Action) []core.Action {
 	return ret
 }
 
-func (f *fixture) expectUpdateAction(iamidentity *iamauthenticatorv1alpha1.IAMIdentityMapping) {
-	action := core.NewRootUpdateAction(schema.GroupVersionResource{Group: iamauthenticator.GroupName, Resource: "iamidentitymappings"}, iamidentity)
-	f.actions = append(f.actions, action)
-}
-
 func (f *fixture) expectUpdateStatusAction(iamidentity *iamauthenticatorv1alpha1.IAMIdentityMapping) {
 	action := core.NewRootUpdateSubresourceAction(schema.GroupVersionResource{Group: iamauthenticator.GroupName, Resource: "iamidentitymappings"}, "status", iamidentity)
 	f.actions = append(f.actions, action)
 }
 
-func (f *fixture) expectCreateAction(iamidentity *iamauthenticatorv1alpha1.IAMIdentityMapping) {
-	action := core.NewRootCreateAction(schema.GroupVersionResource{Group: iamauthenticator.GroupName, Resource: "iamidentitymappings"}, iamidentity)
-	f.actions = append(f.actions, action)
-}
-
 func getKey(iamidentity *iamauthenticatorv1alpha1.IAMIdentityMapping, t *testing.T) string {
 	key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(iamidentity)
 	if err != nil {
diff --git a/pkg/mapper/dynamicfile/dynamicfile_test.go b/pkg/mapper/dynamicfile/dynamicfile_test.go
index 34503710..87afafea 100644
--- a/pkg/mapper/dynamicfile/dynamicfile_test.go
+++ b/pkg/mapper/dynamicfile/dynamicfile_test.go
@@ -25,8 +25,8 @@ func TestMain(m *testing.M) {
 	m.Run()
 }
 
-func makeStore(users map[string]config.UserMapping, roles map[string]config.RoleMapping, filename string, userIDStrict bool) DynamicFileMapStore {
-	ms := DynamicFileMapStore{
+func makeStore(users map[string]config.UserMapping, roles map[string]config.RoleMapping, filename string, userIDStrict bool) *DynamicFileMapStore {
+	ms := &DynamicFileMapStore{
 		users:        users,
 		roles:        roles,
 		awsAccounts:  make(map[string]interface{}),
@@ -38,7 +38,7 @@ func makeStore(users map[string]config.UserMapping, roles map[string]config.Role
 	return ms
 }
 
-func makeDefaultStore() DynamicFileMapStore {
+func makeDefaultStore() *DynamicFileMapStore {
 	users := make(map[string]config.UserMapping)
 	roles := make(map[string]config.RoleMapping)
 	users["arn:aws:iam::012345678912:user/matt"] = testUser
@@ -49,7 +49,7 @@ func makeDefaultStore() DynamicFileMapStore {
 func makeMapper(users map[string]config.UserMapping, roles map[string]config.RoleMapping, filename string, userIDStrict bool) *DynamicFileMapper {
 	store := makeStore(users, roles, filename, userIDStrict)
 	return &DynamicFileMapper{
-		DynamicFileMapStore: &store,
+		DynamicFileMapStore: store,
 	}
 }
 
@@ -220,14 +220,18 @@ func TestUserIdStrict(t *testing.T) {
 	fileutil.StartLoadDynamicFile(ms.filename, ms, stopCh)
 	time.Sleep(1 * time.Second)
 	ms.mutex.RLock()
-	for key, _ := range ms.roles {
+	for key := range ms.roles {
 		if key[0:6] != "userid" {
 			t.Errorf("failed to generate key for userIDStrict")
 		}
 	}
 	ms.mutex.RUnlock()
 	//clean test files
-	defer os.Remove("/tmp/test.txt")
+	defer func() {
+		if err := os.Remove("/tmp/test.txt"); err != nil {
+			t.Errorf("failed to delete a local file /tmp/test.txt")
+		}
+	}()
 }
 
 func TestWithoutUserIdStrict(t *testing.T) {
@@ -251,14 +255,18 @@ func TestWithoutUserIdStrict(t *testing.T) {
 	fileutil.StartLoadDynamicFile(ms.filename, ms, stopCh)
 	time.Sleep(1 * time.Second)
 	ms.mutex.RLock()
-	for key, _ := range ms.roles {
+	for key := range ms.roles {
 		if key[0:3] != "arn" {
 			t.Errorf("failed to generate key for userIDStrict")
 		}
 	}
 	ms.mutex.RUnlock()
 	//clean test files
-	defer os.Remove("/tmp/test.txt")
+	defer func() {
+		if err := os.Remove("/tmp/test.txt"); err != nil {
+			t.Errorf("failed to delete a local file /tmp/test.txt")
+		}
+	}()
 }
 
 func TestLoadDynamicFileMode(t *testing.T) {
@@ -311,7 +319,9 @@ func TestLoadDynamicFileMode(t *testing.T) {
 	ms.mutex.RUnlock()
 	//user update the dynamic file,expect mapping should be equal to expectedMapStore
 	expectedData := []byte(updatedFileContent)
-	err = os.WriteFile("/tmp/expected.txt", expectedData, 0600)
+	if err = os.WriteFile("/tmp/expected.txt", expectedData, 0600); err != nil {
+		t.Errorf("failed to create expected local file /tmp/expected.txt")
+	}
 
 	cfg = config.Config{
 		DynamicFileUserIDStrict: true,
@@ -384,9 +394,16 @@ func TestLoadDynamicFileMode(t *testing.T) {
 	}
 	ms.mutex.RUnlock()
 	//clean test files
-	defer os.Remove("/tmp/test.txt")
-	defer os.Remove("/tmp/expected.txt")
-
+	defer func() {
+		if err := os.Remove("/tmp/test.txt"); err != nil {
+			t.Errorf("failed to delete a local file /tmp/test.txt")
+		}
+	}()
+	defer func() {
+		if err := os.Remove("/tmp/expected.txt"); err != nil {
+			t.Errorf("failed to delete a local file /tmp/expected.txt")
+		}
+	}()
 }
 
 func TestCallBackForFileDeletion(t *testing.T) {
diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go
index 30e73629..126a2652 100644
--- a/pkg/server/server_test.go
+++ b/pkg/server/server_test.go
@@ -285,7 +285,7 @@ func TestAuthenticateUnableToDecodeBodyCRD(t *testing.T) {
 	validateMetrics(t, validateOpts{malformed: 1})
 }
 
-func testIsLoggableIdentity(t *testing.T) {
+func TestIsLoggableIdentity(t *testing.T) {
 	h := &handler{scrubbedAccounts: []string{"111122223333", "012345678901"}}
 
 	cases := []struct {
@@ -555,7 +555,9 @@ func TestAuthenticateVerifierRoleMappingCRD(t *testing.T) {
 		SessionName:  "TestSession",
 	}})
 	indexer := createIndexer()
-	indexer.Add(newIAMIdentityMapping("arn:aws:iam::0123456789012:role/Test", "arn:aws:iam::0123456789012:role/test", "TestUser", []string{"sys:admin", "listers"}))
+	if err := indexer.Add(newIAMIdentityMapping("arn:aws:iam::0123456789012:role/Test", "arn:aws:iam::0123456789012:role/test", "TestUser", []string{"sys:admin", "listers"})); err != nil {
+		t.Fatalf("Could not add IAM identity mapping: %v", err)
+	}
 	h.backendMapper = BackendMapper{
 		mappers:      []mapper.Mapper{crd.NewCRDMapperWithIndexer(indexer)},
 		mapperStopCh: make(chan struct{}),
@@ -647,7 +649,9 @@ func TestAuthenticateVerifierUserMappingCRD(t *testing.T) {
 		SessionName:  "TestSession",
 	}})
 	indexer := createIndexer()
-	indexer.Add(newIAMIdentityMapping("arn:aws:iam::0123456789012:user/Test", "arn:aws:iam::0123456789012:user/test", "TestUser", []string{"sys:admin", "listers"}))
+	if err := indexer.Add(newIAMIdentityMapping("arn:aws:iam::0123456789012:user/Test", "arn:aws:iam::0123456789012:user/test", "TestUser", []string{"sys:admin", "listers"})); err != nil {
+		t.Fatalf("Could not add IAM identity mapping: %v", err)
+	}
 	h.backendMapper = BackendMapper{
 		mappers:      []mapper.Mapper{crd.NewCRDMapperWithIndexer(indexer)},
 		mapperStopCh: make(chan struct{}),
@@ -918,7 +922,9 @@ func TestAuthenticateVerifierNodeMappingCRD(t *testing.T) {
 	}})
 	h.ec2Provider = newTestEC2Provider("ip-172-31-27-14", 15, 5)
 	indexer := createIndexer()
-	indexer.Add(newIAMIdentityMapping("arn:aws:iam::0123456789012:role/TestNodeRole", "arn:aws:iam::0123456789012:role/testnoderole", "system:node:{{EC2PrivateDNSName}}", []string{"system:nodes", "system:bootstrappers"}))
+	if err := indexer.Add(newIAMIdentityMapping("arn:aws:iam::0123456789012:role/TestNodeRole", "arn:aws:iam::0123456789012:role/testnoderole", "system:node:{{EC2PrivateDNSName}}", []string{"system:nodes", "system:bootstrappers"})); err != nil {
+		t.Fatalf("Could not add IAM identity mapping: %v", err)
+	}
 	h.backendMapper = BackendMapper{
 		mappers:      []mapper.Mapper{crd.NewCRDMapperWithIndexer(indexer)},
 		mapperStopCh: make(chan struct{}),
@@ -952,13 +958,6 @@ func TestRenderTemplate(t *testing.T) {
 		identity token.Identity
 		err      bool
 	}{
-		{
-			template: "a-{{EC2PrivateDNSName}}-b",
-			want:     "a-ip-172-31-27-14-b",
-			identity: token.Identity{
-				SessionName: "i-aaaaaaaa",
-			},
-		},
 		{
 			template: "a-{{EC2PrivateDNSName}}-b",
 			want:     "a-ip-172-31-27-14-b",
diff --git a/pkg/token/token_test.go b/pkg/token/token_test.go
index 9e94457c..506e9474 100644
--- a/pkg/token/token_test.go
+++ b/pkg/token/token_test.go
@@ -273,7 +273,7 @@ func TestSTSEndpointResolution(t *testing.T) {
 }
 
 func TestVerifyTokenPreSTSValidations(t *testing.T) {
-	b := make([]byte, maxTokenLenBytes+1, maxTokenLenBytes+1)
+	b := make([]byte, maxTokenLenBytes+1)
 	s := string(b)
 	validationErrorTest(t, "aws", s, "token is too large")
 	validationErrorTest(t, "aws", "k8s-aws-v2.asdfasdfa", "token is missing expected \"k8s-aws-v1.\" prefix")
@@ -321,7 +321,9 @@ func TestVerifyHTTP403(t *testing.T) {
 
 func TestVerifyNoRedirectsFollowed(t *testing.T) {
 	ts2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		fmt.Fprintln(w, `{"UserId":"AROAIIRR6I5NDJBWMIRQQ:admin-session","Account":"111122223333","Arn":"arn:aws:sts::111122223333:assumed-role/Admin/admin-session"}`)
+		if _, err := fmt.Fprintln(w, `{"UserId":"AROAIIRR6I5NDJBWMIRQQ:admin-session","Account":"111122223333","Arn":"arn:aws:sts::111122223333:assumed-role/Admin/admin-session"}`); err != nil {
+			t.Errorf("Unexpected error: %v", err)
+		}
 	}))
 	defer ts2.Close()
 
@@ -337,7 +339,11 @@ func TestVerifyNoRedirectsFollowed(t *testing.T) {
 		t.Errorf("Unexpected error: %v", err)
 		return
 	}
-	defer resp.Body.Close()
+	defer func() {
+		if err := resp.Body.Close(); err != nil {
+			t.Errorf("Error closing response body: %v", err)
+		}
+	}()
 	if resp.Header.Get("Location") != ts2.URL && resp.StatusCode != http.StatusFound {
 		body, _ := io.ReadAll(resp.Body)
 		fmt.Printf("%#v\n", resp)
@@ -486,19 +492,23 @@ func TestFormatJson(t *testing.T) {
 					})
 				}
 
-				os.Setenv(c.EnvKey, string(marshal))
+				if err := os.Setenv(c.EnvKey, string(marshal)); err != nil {
+					t.Errorf("failed to set env var %s: %v", c.EnvKey, err)
+				}
 			}
 
 			jsonResponse := g.FormatJSON(Token{Token: token, Expiration: expiry})
 			output := &clientauthentication.ExecCredential{}
-			json.Unmarshal([]byte(jsonResponse), output)
+			if err := json.Unmarshal([]byte(jsonResponse), output); err != nil {
+				t.Errorf("failed to unmarshal json response: %v", err)
+			}
 
-			if output.TypeMeta.Kind != kindExecCredential {
-				t.Errorf("expected Kind to be %s but was %s", kindExecCredential, output.TypeMeta.Kind)
+			if output.Kind != kindExecCredential {
+				t.Errorf("expected Kind to be %s but was %s", kindExecCredential, output.Kind)
 			}
 
-			if output.TypeMeta.APIVersion != c.ExpectApiVersion {
-				t.Errorf("expected APIVersion to be %s but was %s", c.ExpectApiVersion, output.TypeMeta.APIVersion)
+			if output.APIVersion != c.ExpectApiVersion {
+				t.Errorf("expected APIVersion to be %s but was %s", c.ExpectApiVersion, output.APIVersion)
 			}
 
 			if output.Status.Token != token {
@@ -509,7 +519,9 @@ func TestFormatJson(t *testing.T) {
 				t.Errorf("expected expiration to be %s but was %s", expiry, output.Status.ExpirationTimestamp)
 			}
 
-			os.Unsetenv(c.EnvKey)
+			if err := os.Unsetenv(c.EnvKey); err != nil {
+				t.Errorf("failed to unset env var %s: %v", c.EnvKey, err)
+			}
 		})
 	}
 }