diff --git a/.gitlab/ci/Dockerfile b/.gitlab/ci/Dockerfile
index a96618ac46540b64a0d582a84df19628e8a091c4..e49acc4d5c91eff9bbfa77de6157ef53e8650563 100644
--- a/.gitlab/ci/Dockerfile
+++ b/.gitlab/ci/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.21.1-alpine3.18
+FROM golang:1.21.3-alpine3.18
 
 # Force build - 2022-10-03T17:42:00+0000
 RUN apk add --no-cache make git py-pip bash curl && \
diff --git a/.gitlab/ci/yaml/_common.gitlab-ci.yml b/.gitlab/ci/yaml/_common.gitlab-ci.yml
index 98e08fe20e6958e415578a2fa025ee1d3654c25d..a6b26e98c44d395841457bc12709a79196b492ae 100644
--- a/.gitlab/ci/yaml/_common.gitlab-ci.yml
+++ b/.gitlab/ci/yaml/_common.gitlab-ci.yml
@@ -1,6 +1,6 @@
 variables:
   USE_CONTAINER: "true"
-  CI_IMAGE: registry.gitlab.com/gitlab-org/ci-cd/docker-machine/ci:go1.21.1-alpine3.18
+  CI_IMAGE: registry.gitlab.com/gitlab-org/ci-cd/docker-machine/ci:go1.21.3-alpine3.18
   DOCKER_VERSION: "20.10.12"
 
 default:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1b5f30ee17768bbf281583ab9b385a894f4f0744..55b6e79e6df2b1167ffdde294391b32d07dcd1b2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -72,9 +72,6 @@ to clean-up build results.
 
 ## Tests and validation
 
-We use the usual `go` tools for this, to run those commands you need at least the linter which you can
-install with `go get -u golang.org/x/lint/golint`
-
 To run basic validation (fmt, test-short, lint, vet), and the project unit tests, call:
 
     $ make test
diff --git a/Dockerfile b/Dockerfile
index 935de0e6629fcfd6a23dacbfca27318253ac3224..38863dbdc676516f83f0e544f75012034dc1644c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,20 +1,14 @@
-FROM golang:1.12.9
+FROM golang:1.21.3
 
 RUN apt-get update && apt-get install -y --no-install-recommends \
                 openssh-client \
                 rsync \
-                fuse \
+                fuse3 \
                 sshfs \
         && rm -rf /var/lib/apt/lists/*
 
 ENV GO111MODULE=on
 
-RUN go get golang.org/x/tools@v0.1.12
-RUN go get golang.org/x/lint/golint
-RUN go get golang.org/x/tools/cover
-
-ENV GO111MODULE=off
-
 ENV USER root
 WORKDIR /go/src/github.com/docker/machine
 
diff --git a/appveyor.yml b/appveyor.yml
index a32b5620fc4385b45a27f099bb2721e076e0f3c1..3fbdd1ee8609961952c0c75c255ac9e86d54815a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -10,7 +10,7 @@ environment:
 clone_folder: c:\gopath\src\github.com\docker\machine
 
 build_script:
-  - go build -i -o ./bin/docker-machine.exe ./cmd/docker-machine
+  - go build -o ./bin/docker-machine.exe ./cmd/docker-machine
 
 test_script:
   - powershell -Command go test -v ./libmachine/shell
diff --git a/commands/scp_unix.go b/commands/scp_unix.go
index d26cf384e2128644c05001b7ad30291f3bc16089..b483449a69e7c5a5bb48df847e7923bdf2350922 100644
--- a/commands/scp_unix.go
+++ b/commands/scp_unix.go
@@ -1,3 +1,4 @@
+//go:build !windows
 // +build !windows
 
 package commands
diff --git a/drivers/virtualbox/vtx_intel.go b/drivers/virtualbox/vtx_intel.go
index 852f451d13793051b76e0fc453e2e0cbf36ebc02..2d8088f62703f39efa5def695f025a60c5b50e3d 100644
--- a/drivers/virtualbox/vtx_intel.go
+++ b/drivers/virtualbox/vtx_intel.go
@@ -1,3 +1,4 @@
+//go:build 386 || amd64
 // +build 386 amd64
 
 package virtualbox
diff --git a/drivers/virtualbox/vtx_other.go b/drivers/virtualbox/vtx_other.go
index 5dbfd17553b1d8f8b4aa33f55f777e686005c5e0..f984ac3fb7c283a96d9c4054ef853b589d98b80e 100644
--- a/drivers/virtualbox/vtx_other.go
+++ b/drivers/virtualbox/vtx_other.go
@@ -1,3 +1,4 @@
+//go:build !386 && !amd64
 // +build !386,!amd64
 
 package virtualbox
diff --git a/drivers/vmwarefusion/fusion.go b/drivers/vmwarefusion/fusion.go
index be433e5fe7d56ba9a781a5f0c2ece7cab459970e..e2d588a2dcadc16131e51634b3560c8de7073e22 100644
--- a/drivers/vmwarefusion/fusion.go
+++ b/drivers/vmwarefusion/fusion.go
@@ -1,3 +1,4 @@
+//go:build !darwin
 // +build !darwin
 
 package vmwarefusion
diff --git a/go.mod b/go.mod
index 249963bdcad9818bb48b6e86a1d91dd404edb42f..ab3229bb8c9c286290402410ed9391ae02f22aee 100644
--- a/go.mod
+++ b/go.mod
@@ -18,10 +18,10 @@ require (
 	github.com/stretchr/testify v1.7.0
 	github.com/vmware/govcloudair v0.0.2
 	github.com/vmware/govmomi v0.6.2
-	golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
-	golang.org/x/net v0.6.0
+	golang.org/x/crypto v0.14.0
+	golang.org/x/net v0.17.0
 	golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558
-	golang.org/x/sys v0.12.0
+	golang.org/x/sys v0.13.0
 	google.golang.org/api v0.42.0
 )
 
@@ -56,8 +56,8 @@ require (
 	github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9 // indirect
 	go.opencensus.io v0.23.0 // indirect
 	golang.org/x/mod v0.8.0 // indirect
-	golang.org/x/term v0.12.0
-	golang.org/x/text v0.7.0 // indirect
+	golang.org/x/term v0.13.0
+	golang.org/x/text v0.13.0 // indirect
 	golang.org/x/tools v0.6.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/genproto v0.0.0-20210323160006-e668133fea6a // indirect
diff --git a/go.sum b/go.sum
index 139ffd7ec2177091cce9fc4213b2f5556488c2c6..bb1dbaab60a10da288b93ddaed256d5e1c205a54 100644
--- a/go.sum
+++ b/go.sum
@@ -239,8 +239,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -309,8 +310,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
-golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
-golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -372,11 +373,11 @@ golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210314195730-07df6a141424/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
-golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
-golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
+golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
+golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -384,8 +385,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
diff --git a/libmachine/drivers/plugin/localbinary/plugin.go b/libmachine/drivers/plugin/localbinary/plugin.go
index c431c7eda9d7174fe98c66c08e6216cb8b5b18bd..ae32b1e9d9bae7afa5958edec831c0de2c985afa 100644
--- a/libmachine/drivers/plugin/localbinary/plugin.go
+++ b/libmachine/drivers/plugin/localbinary/plugin.go
@@ -93,9 +93,11 @@ func (e ErrPluginBinaryNotFound) Error() string {
 }
 
 // driverPath finds the path of a driver binary by its name.
-//  + If the driver is a core driver, there is no separate driver binary. We reuse current binary if it's `docker-machine`
+//   - If the driver is a core driver, there is no separate driver binary. We reuse current binary if it's `docker-machine`
+//
 // or we assume `docker-machine` is in the PATH.
-//  + If the driver is NOT a core driver, then the separate binary must be in the PATH and it's name must be
+//   - If the driver is NOT a core driver, then the separate binary must be in the PATH and it's name must be
+//
 // `docker-machine-driver-driverName`
 func driverPath(driverName string) string {
 	for _, coreDriver := range CoreDrivers {
diff --git a/libmachine/provision/provisiontest/sshcommander.go b/libmachine/provision/provisiontest/sshcommander.go
index 3f9f8b71d26f83f8f93580ac621aaf036e58c7da..e826cb6859c2cc312fc0e3adc9c334db13c8f592 100644
--- a/libmachine/provision/provisiontest/sshcommander.go
+++ b/libmachine/provision/provisiontest/sshcommander.go
@@ -1,21 +1,21 @@
-//Package provisiontest provides utilities for testing provisioners
+// Package provisiontest provides utilities for testing provisioners
 package provisiontest
 
 import "errors"
 
-//FakeSSHCommanderOptions is intended to create a FakeSSHCommander without actually knowing the underlying sshcommands by passing it to NewSSHCommander
+// FakeSSHCommanderOptions is intended to create a FakeSSHCommander without actually knowing the underlying sshcommands by passing it to NewSSHCommander
 type FakeSSHCommanderOptions struct {
 	//Result of the ssh command to look up the FilesystemType
 	FilesystemType string
 }
 
-//FakeSSHCommander is an implementation of provision.SSHCommander to provide predictable responses set by testing code
-//Extend it when needed
+// FakeSSHCommander is an implementation of provision.SSHCommander to provide predictable responses set by testing code
+// Extend it when needed
 type FakeSSHCommander struct {
 	Responses map[string]string
 }
 
-//NewFakeSSHCommander creates a FakeSSHCommander without actually knowing the underlying sshcommands
+// NewFakeSSHCommander creates a FakeSSHCommander without actually knowing the underlying sshcommands
 func NewFakeSSHCommander(options FakeSSHCommanderOptions) *FakeSSHCommander {
 	if options.FilesystemType == "" {
 		options.FilesystemType = "ext4"
@@ -29,7 +29,7 @@ func NewFakeSSHCommander(options FakeSSHCommanderOptions) *FakeSSHCommander {
 	return sshCmder
 }
 
-//SSHCommand is an implementation of provision.SSHCommander.SSHCommand to provide predictable responses set by testing code
+// SSHCommand is an implementation of provision.SSHCommander.SSHCommand to provide predictable responses set by testing code
 func (sshCmder *FakeSSHCommander) SSHCommand(args string) (string, error) {
 	response, commandRegistered := sshCmder.Responses[args]
 	if !commandRegistered {
diff --git a/libmachine/shell/shell.go b/libmachine/shell/shell.go
index d0a271c9a9acfa1791b87a6b9144289b427eff58..348b369f7a2bc02fce11a6d76a615971680378ff 100644
--- a/libmachine/shell/shell.go
+++ b/libmachine/shell/shell.go
@@ -1,3 +1,4 @@
+//go:build !windows
 // +build !windows
 
 package shell
diff --git a/libmachine/shell/shell_unix_test.go b/libmachine/shell/shell_unix_test.go
index b9382071b39d8def6e6e81acd6d08b9d59e9cc30..16a76675f5a61c23d4fdb57f239b19b56d6b3a20 100644
--- a/libmachine/shell/shell_unix_test.go
+++ b/libmachine/shell/shell_unix_test.go
@@ -1,3 +1,4 @@
+//go:build !windows
 // +build !windows
 
 package shell
diff --git a/mk/main.mk b/mk/main.mk
index 5f63036049049e5be024ee8718a50d232d704595..2e24ee928e865289e80e87b01dc25f1763dd5b82 100644
--- a/mk/main.mk
+++ b/mk/main.mk
@@ -3,11 +3,7 @@ GO_LDFLAGS := -X `go list ./version`.GitCommit=`git rev-parse --short HEAD 2>/de
 GO_GCFLAGS :=
 
 # Full package list
-PKGS := $(shell go list -tags "$(BUILDTAGS)" ./... | grep -v "/vendor/" | grep -v "/cmd")
-
-# Resolving binary dependencies for specific targets
-GOLINT_BIN := $(GOPATH)/bin/golint
-GOLINT := $(shell [ -x $(GOLINT_BIN) ] && echo $(GOLINT_BIN) || echo '')
+PKGS := $(shell go list -tags "$(BUILDTAGS)" ./... | grep -v "/cmd")
 
 # Honor debug
 ifeq ($(DEBUG),true)
diff --git a/mk/validate.mk b/mk/validate.mk
index 5c05d6f184460749b70788c7a3c05d640929ebdc..b449018e1b0069bc56479019be005a5d3bc07f20 100644
--- a/mk/validate.mk
+++ b/mk/validate.mk
@@ -1,10 +1,12 @@
 fmt:
-	@test -z "$$(gofmt -s -l . 2>&1 | grep -v vendor/ | tee /dev/stderr)"
+	@go mod download
+	@test -z "$$(gofmt -s -l . 2>&1 | tee /dev/stderr)"
 
 vet:
+	@go mod download
 	@test -z "$$(go vet $(PKGS) 2>&1 | tee /dev/stderr)"
 
 lint:
-	$(if $(GOLINT), , \
-		$(error Please install golint: go get -u golang.org/x/lint/golint))
-	@test -z "$$($(GOLINT) ./... 2>&1 | grep -v vendor/ | grep -v "cli/" | grep -v "amazonec2/" |grep -v "openstack/" |grep -v "softlayer/" | grep -v "should have comment" | tee /dev/stderr)"
+	@go mod download
+	@go install golang.org/x/lint/golint@latest
+	@test -z "$$(golint ./... 2>&1 | grep -v "cli/" | grep -v "amazonec2/" |grep -v "openstack/" |grep -v "softlayer/" | grep -v "should have comment" | tee /dev/stderr)"