diff --git a/README.md b/README.md
index 01ee24606014ca1e7242d43b747f772a98fb468b..0557738ffb4da655d9abc05238c29a4e1c8f4c72 100644
--- a/README.md
+++ b/README.md
@@ -15,8 +15,8 @@ You can find sources and pre-compiled binaries [here](https://github.com/JonasPr
 
 ```bash
 # Download the binary (this example downloads the binary for linux amd64)
-$ wget https://github.com/JonasProgrammer/docker-machine-driver-hetzner/releases/download/3.12.2/docker-machine-driver-hetzner_3.12.2_linux_amd64.tar.gz
-$ tar -xvf docker-machine-driver-hetzner_3.12.2_linux_amd64.tar.gz
+$ wget https://github.com/JonasProgrammer/docker-machine-driver-hetzner/releases/download/3.13.0/docker-machine-driver-hetzner_3.13.0_linux_amd64.tar.gz
+$ tar -xvf docker-machine-driver-hetzner_3.13.0_linux_amd64.tar.gz
 
 # Make it executable and copy the binary in a directory accessible with your $PATH
 $ chmod +x docker-machine-driver-hetzner
@@ -91,7 +91,8 @@ $ docker-machine create \
 ## Options
 
 - `--hetzner-api-token`: **required**. Your project-specific access token for the Hetzner Cloud API.
-- `--hetzner-image`: The name of the Hetzner Cloud image to use, see [Images API](https://docs.hetzner.cloud/#resources-images-get) for how to get a list (defaults to `ubuntu-18.04`).
+- `--hetzner-image`: The name (or ID) of the Hetzner Cloud image to use, see [Images API](https://docs.hetzner.cloud/#resources-images-get) for how to get a list (defaults to `ubuntu-18.04`).
+- `--hetzner-image`: The architecture to use during image lookup, inferred from the server type if not explicitly given.
 - `--hetzner-image-id`: The id of the Hetzner cloud image (or snapshot) to use, see [Images API](https://docs.hetzner.cloud/#resources-images-get) for how to get a list (mutually excludes `--hetzner-image`).
 - `--hetzner-server-type`: The type of the Hetzner Cloud server, see [Server Types API](https://docs.hetzner.cloud/#resources-server-types-get) for how to get a list (defaults to `cx11`).
 - `--hetzner-server-location`: The location to create the server in, see [Locations API](https://docs.hetzner.cloud/#resources-locations-get) for how to get a list.
@@ -115,6 +116,15 @@ $ docker-machine create \
 - `--hetzner-primary-ipv4/6`: Sets an existing primary IP (v4 or v6 respectively) for the server, as documented in [Networking](#networking)
 - `--hetzner-wait-on-error`: Amount of seconds to wait on server creation failure (0/no wait by default)
 
+#### Image selection
+
+When `--hetzner-image-id` is passed, it will be used for lookup by ID as-is. No additional validation is performed, and it is mutually exclusive with
+other `--hetzner-image*`-flags.
+
+When `--hetzner-image` is passed, lookup will happen either by name or by ID as per Hetzner-supplied logic. The lookup mechanism will filter by image
+architecture, which is usually inferred from the server type. One may explicitly specify it using `--hetzner-image-arch` in which case the user
+supplied value will take precedence.
+
 #### Existing SSH keys
 
 When you specify the `--hetzner-existing-key-path` option, the driver will attempt to copy `(specified file name)`
@@ -136,6 +146,7 @@ was used during creation.
 |---------------------------------|-------------------------------| -------------------------- |
 | **`--hetzner-api-token`**       | `HETZNER_API_TOKEN`           |                            |
 | `--hetzner-image`               | `HETZNER_IMAGE`               | `ubuntu-18.04`             |
+| `--hetzner-image-arch`          | `HETZNER_IMAGE_ARCH`          | *(infer from server)*      |
 | `--hetzner-image-id`            | `HETZNER_IMAGE_ID`            |                            |
 | `--hetzner-server-type`         | `HETZNER_TYPE`                | `cx11`                     |
 | `--hetzner-server-location`     | `HETZNER_LOCATION`            | *(let Hetzner choose)*     |
diff --git a/driver.go b/driver.go
index 26fe7b109c4923a3220992ffe5ce2ff7b6b3823c..f8ad6b2b9ac8c3e437a0f05ed17732282b8522f9 100644
--- a/driver.go
+++ b/driver.go
@@ -26,6 +26,7 @@ type Driver struct {
 	AccessToken       string
 	Image             string
 	ImageID           int
+	ImageArch         hcloud.Architecture
 	cachedImage       *hcloud.Image
 	Type              string
 	cachedType        *hcloud.ServerType
@@ -69,6 +70,7 @@ const (
 	flagAPIToken          = "hetzner-api-token"
 	flagImage             = "hetzner-image"
 	flagImageID           = "hetzner-image-id"
+	flagImageArch         = "hetzner-image-arch"
 	flagType              = "hetzner-server-type"
 	flagLocation          = "hetzner-server-location"
 	flagExKeyID           = "hetzner-existing-key-id"
@@ -108,6 +110,8 @@ const (
 	legacyFlagUserDataFromFile = "hetzner-user-data-from-file"
 	legacyFlagDisablePublic4   = "hetzner-disable-public-4"
 	legacyFlagDisablePublic6   = "hetzner-disable-public-6"
+
+	emptyImageArchitecture = hcloud.Architecture("")
 )
 
 // NewDriver initializes a new driver instance; see [drivers.Driver.NewDriver]
@@ -144,6 +148,11 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
 			Name:   flagImageID,
 			Usage:  "Image to use for server creation",
 		},
+		mcnflag.StringFlag{
+			EnvVar: "HETZNER_IMAGE_ARCH",
+			Name:   flagImageArch,
+			Usage:  "Image architecture for lookup to use for server creation",
+		},
 		mcnflag.StringFlag{
 			EnvVar: "HETZNER_TYPE",
 			Name:   flagType,
@@ -305,12 +314,16 @@ func (d *Driver) setConfigFromFlagsImpl(opts drivers.DriverOptions) error {
 	d.AccessToken = opts.String(flagAPIToken)
 	d.Image = opts.String(flagImage)
 	d.ImageID = opts.Int(flagImageID)
+	err := d.setImageArch(opts.String(flagImageArch))
+	if err != nil {
+		return err
+	}
 	d.Location = opts.String(flagLocation)
 	d.Type = opts.String(flagType)
 	d.KeyID = opts.Int(flagExKeyID)
 	d.IsExistingKey = d.KeyID != 0
 	d.originalKey = opts.String(flagExKeyPath)
-	err := d.setUserDataFlags(opts)
+	err = d.setUserDataFlags(opts)
 	if err != nil {
 		return err
 	}
@@ -349,12 +362,45 @@ func (d *Driver) setConfigFromFlagsImpl(opts drivers.DriverOptions) error {
 		return d.flagFailure("hetzner requires --%v to be set", flagAPIToken)
 	}
 
+	if err = d.verifyImageFlags(); err != nil {
+		return err
+	}
+
+	if err = d.verifyNetworkFlags(); err != nil {
+		return err
+	}
+
+	instrumented(d)
+
+	return nil
+}
+
+func (d *Driver) setImageArch(arch string) error {
+	switch arch {
+	case "":
+		d.ImageArch = emptyImageArchitecture
+	case string(hcloud.ArchitectureARM):
+		d.ImageArch = hcloud.ArchitectureARM
+	case string(hcloud.ArchitectureX86):
+		d.ImageArch = hcloud.ArchitectureX86
+	default:
+		return errors.Errorf("unknown architecture %v", arch)
+	}
+	return nil
+}
+
+func (d *Driver) verifyImageFlags() error {
 	if d.ImageID != 0 && d.Image != "" && d.Image != defaultImage /* support legacy behaviour */ {
 		return d.flagFailure("--%v and --%v are mutually exclusive", flagImage, flagImageID)
+	} else if d.ImageID != 0 && d.ImageArch != "" {
+		return d.flagFailure("--%v and --%v are mutually exclusive", flagImageArch, flagImageID)
 	} else if d.ImageID == 0 && d.Image == "" {
 		d.Image = defaultImage
 	}
+	return nil
+}
 
+func (d *Driver) verifyNetworkFlags() error {
 	if d.DisablePublic4 && d.DisablePublic6 && !d.UsePrivateNetwork {
 		return d.flagFailure("--%v must be used if public networking is disabled (hint: implicitly set by --%v)",
 			flagUsePrivateNetwork, flagDisablePublic)
@@ -367,9 +413,6 @@ func (d *Driver) setConfigFromFlagsImpl(opts drivers.DriverOptions) error {
 	if d.DisablePublic6 && d.PrimaryIPv6 != "" {
 		return d.flagFailure("--%v and --%v are mutually exclusive", flagPrimary6, flagDisablePublic6)
 	}
-
-	instrumented(d)
-
 	return nil
 }
 
@@ -437,35 +480,14 @@ func (d *Driver) setLabelsFromFlags(opts drivers.DriverOptions) error {
 
 // PreCreateCheck validates the Driver data is in a valid state for creation; see [drivers.Driver.PreCreateCheck]
 func (d *Driver) PreCreateCheck() error {
-	if d.IsExistingKey {
-		if d.originalKey == "" {
-			return d.flagFailure("specifying an existing key ID requires the existing key path to be set as well")
-		}
-
-		key, err := d.getKey()
-		if err != nil {
-			return errors.Wrap(err, "could not get key")
-		}
-
-		buf, err := os.ReadFile(d.originalKey + ".pub")
-		if err != nil {
-			return errors.Wrap(err, "could not read public key")
-		}
-
-		// Will also parse `ssh-rsa w309jwf0e39jf asdf` public keys
-		pubk, _, _, _, err := ssh.ParseAuthorizedKey(buf)
-		if err != nil {
-			return errors.Wrap(err, "could not parse authorized key")
-		}
-
-		if key.Fingerprint != ssh.FingerprintLegacyMD5(pubk) &&
-			key.Fingerprint != ssh.FingerprintSHA256(pubk) {
-			return errors.Errorf("remote key %d does not match local key %s", d.KeyID, d.originalKey)
-		}
+	if err := d.setupExistingKey(); err != nil {
+		return err
 	}
 
-	if _, err := d.getType(); err != nil {
+	if serverType, err := d.getType(); err != nil {
 		return errors.Wrap(err, "could not get type")
+	} else if d.ImageArch != "" && serverType.Architecture != d.ImageArch {
+		log.Warnf("supplied architecture %v differs from server architecture %v", d.ImageArch, serverType.Architecture)
 	}
 
 	if _, err := d.getImage(); err != nil {
@@ -495,6 +517,39 @@ func (d *Driver) PreCreateCheck() error {
 	return nil
 }
 
+func (d *Driver) setupExistingKey() error {
+	if !d.IsExistingKey {
+		return nil
+	}
+
+	if d.originalKey == "" {
+		return d.flagFailure("specifying an existing key ID requires the existing key path to be set as well")
+	}
+
+	key, err := d.getKey()
+	if err != nil {
+		return errors.Wrap(err, "could not get key")
+	}
+
+	buf, err := os.ReadFile(d.originalKey + ".pub")
+	if err != nil {
+		return errors.Wrap(err, "could not read public key")
+	}
+
+	// Will also parse `ssh-rsa w309jwf0e39jf asdf` public keys
+	pubk, _, _, _, err := ssh.ParseAuthorizedKey(buf)
+	if err != nil {
+		return errors.Wrap(err, "could not parse authorized key")
+	}
+
+	if key.Fingerprint != ssh.FingerprintLegacyMD5(pubk) &&
+		key.Fingerprint != ssh.FingerprintSHA256(pubk) {
+		return errors.Errorf("remote key %d does not match local key %s", d.KeyID, d.originalKey)
+	}
+
+	return nil
+}
+
 // Create actually creates the hetzner-cloud server; see [drivers.Driver.Create]
 func (d *Driver) Create() error {
 	err := d.prepareLocalKey()
@@ -872,26 +927,8 @@ func (d *Driver) GetState() (state.State, error) {
 
 // Remove deletes the hetzner server and additional resources created during creation; see [drivers.Driver.Remove]
 func (d *Driver) Remove() error {
-	if d.ServerID != 0 {
-		srv, err := d.getServerHandle()
-		if err != nil {
-			return errors.Wrap(err, "could not get server handle")
-		}
-
-		if srv == nil {
-			log.Infof(" -> Server does not exist anymore")
-		} else {
-			log.Infof(" -> Destroying server %s[%d] in...", srv.Name, srv.ID)
-
-			if _, err := d.getClient().Server.Delete(context.Background(), srv); err != nil {
-				return errors.Wrap(err, "could not delete server")
-			}
-
-			// failure to remove a placement group is not a hard error
-			if softErr := d.removeEmptyServerPlacementGroup(srv); softErr != nil {
-				log.Error(softErr)
-			}
-		}
+	if err := d.destroyServer(); err != nil {
+		return err
 	}
 
 	// failure to remove a key is not ha hard error
@@ -931,6 +968,40 @@ func (d *Driver) Remove() error {
 	return nil
 }
 
+func (d *Driver) destroyServer() error {
+	if d.ServerID == 0 {
+		return nil
+	}
+
+	srv, err := d.getServerHandle()
+	if err != nil {
+		return errors.Wrap(err, "could not get server handle")
+	}
+
+	if srv == nil {
+		log.Infof(" -> Server does not exist anymore")
+	} else {
+		log.Infof(" -> Destroying server %s[%d] in...", srv.Name, srv.ID)
+
+		res, _, err := d.getClient().Server.DeleteWithResult(context.Background(), srv)
+		if err != nil {
+			return errors.Wrap(err, "could not delete server")
+		}
+
+		// failure to remove a placement group is not a hard error
+		if softErr := d.removeEmptyServerPlacementGroup(srv); softErr != nil {
+			log.Error(softErr)
+		}
+
+		// wait for the server to actually be deleted
+		if err = d.waitForAction(res.Action); err != nil {
+			return errors.Wrap(err, "could not wait for deletion")
+		}
+	}
+
+	return nil
+}
+
 // Restart instructs the hetzner cloud server to reboot; see [drivers.Driver.Restart]
 func (d *Driver) Restart() error {
 	srv, err := d.getServerHandle()
@@ -1071,7 +1142,12 @@ func (d *Driver) getImage() (*hcloud.Image, error) {
 			return image, errors.Wrap(err, fmt.Sprintf("could not get image by id %v", d.ImageID))
 		}
 	} else {
-		image, _, err = d.getClient().Image.GetByName(context.Background(), d.Image)
+		arch, err := d.getImageArchitectureForLookup()
+		if err != nil {
+			return nil, errors.Wrap(err, "could not determine image architecture")
+		}
+
+		image, _, err = d.getClient().Image.GetByNameAndArchitecture(context.Background(), d.Image, arch)
 		if err != nil {
 			return image, errors.Wrap(err, fmt.Sprintf("could not get image by name %v", d.Image))
 		}
@@ -1081,6 +1157,19 @@ func (d *Driver) getImage() (*hcloud.Image, error) {
 	return instrumented(image), nil
 }
 
+func (d *Driver) getImageArchitectureForLookup() (hcloud.Architecture, error) {
+	if d.ImageArch != emptyImageArchitecture {
+		return d.ImageArch, nil
+	}
+
+	serverType, err := d.getType()
+	if err != nil {
+		return "", err
+	}
+
+	return serverType.Architecture, nil
+}
+
 func (d *Driver) getKey() (*hcloud.SSHKey, error) {
 	if d.cachedKey != nil {
 		return d.cachedKey, nil
diff --git a/driver_test.go b/driver_test.go
index b3a77f939ea6b926e0c8364564a373d58b1d2a32..5f9ea489dca81d3dfd0a394f1142748113729dc7 100644
--- a/driver_test.go
+++ b/driver_test.go
@@ -3,6 +3,7 @@ package main
 import (
 	"github.com/docker/machine/commands/commandstest"
 	"github.com/docker/machine/libmachine/drivers"
+	"github.com/hetznercloud/hcloud-go/hcloud"
 	"os"
 	"strings"
 	"testing"
@@ -207,6 +208,68 @@ func TestDisablePublic46Legacy(t *testing.T) {
 	}
 }
 
+func TestImageFlagExclusions(t *testing.T) {
+	// both id and name given
+	d := NewDriver()
+	err := d.setConfigFromFlagsImpl(makeFlags(map[string]interface{}{
+		flagImageID: 42,
+		flagImage:   "answer",
+	}))
+	assertMutualExclusion(t, err, flagImageID, flagImage)
+
+	// both id and arch given
+	d = NewDriver()
+	err = d.setConfigFromFlagsImpl(makeFlags(map[string]interface{}{
+		flagImageID:   42,
+		flagImageArch: string(hcloud.ArchitectureX86),
+	}))
+	assertMutualExclusion(t, err, flagImageID, flagImageArch)
+}
+
+func TestImageArch(t *testing.T) {
+	// no explicit arch
+	d := NewDriver()
+	err := d.setConfigFromFlagsImpl(makeFlags(map[string]interface{}{
+		flagImage: "answer",
+	}))
+	if err != nil {
+		t.Fatalf("unexpected error, %v", err)
+	}
+
+	if d.ImageArch != emptyImageArchitecture {
+		t.Errorf("expected empty architecture, but got %v", d.ImageArch)
+	}
+
+	// existing architectures
+	testArchFlag(t, hcloud.ArchitectureARM)
+	testArchFlag(t, hcloud.ArchitectureX86)
+
+	// invalid
+	d = NewDriver()
+	err = d.setConfigFromFlagsImpl(makeFlags(map[string]interface{}{
+		flagImage:     "answer",
+		flagImageArch: "hal9000",
+	}))
+	if err == nil {
+		t.Fatal("expected error, but invalid arch was accepted")
+	}
+}
+
+func testArchFlag(t *testing.T, arch hcloud.Architecture) {
+	d := NewDriver()
+	err := d.setConfigFromFlagsImpl(makeFlags(map[string]interface{}{
+		flagImage:     "answer",
+		flagImageArch: string(arch),
+	}))
+	if err != nil {
+		t.Fatalf("unexpected error, %v", err)
+	}
+
+	if d.ImageArch != arch {
+		t.Errorf("expected %v architecture, but got %v", arch, d.ImageArch)
+	}
+}
+
 func assertMutualExclusion(t *testing.T, err error, flag1, flag2 string) {
 	if err == nil {
 		t.Errorf("expected mutually exclusive flags to fail, but no error was thrown: %v %v", flag1, flag2)