Even when GPT (GUID Partition Table, not the slop thing) didn't exist, I never thought I'd need to deal with and handle the limit of a 2 terabyte partition size on an MBR/DOS formatted disk, it just seems such a huge size it would never be a factor. But, here we are, in 2026, and I have had to deal with this exact issue.

Situation

Backups. We all need them, but they take up space. Where do we put them? Well, there's a few places. Typically I recommend and use BorgBase for an affordable and reasonable amount of online storage. However, I like to co-locate my backups, so I also use one of AlphaVPS's Storage VPS solutions and I've had a 4 terabyte VPS with them for years.
This VPS has been running Rocky Linux since I started using it, but as time went on I felt less and less comfortable - partly because of the RHEL upstream, but mostly because I want ZFS on this VPS. So, I decided to reinstall and use a distro with ZFS support.
Naturally, I could install FreeBSD, as I do on many servers I manage, but AlphaVPS does not have an up to date FreeBSD image, only 14.2 minimal which, sadly, does not install any more as the installation files it needs to download no longer exist on FreeBSD's servers.
However, AlphaVPS do offer a netboot.xyz image from which you can install many other operating systems even if AlphaVPS doesn't have the image on their own systems - Wonderful! Although, netboot.xyz also only have images for FreeBSD 14.2, so the same problem exists.
Guess I'll have to use Linux. That's OK, but I want something lean. Debian would be suitable, and has ZFS support, but does use systemd, which... hmm... is there anything else?

Yes! Alpine Linux is available! Uses OpenRC instead of SystemD and it has ZFS support!

So off I go, running through the Alpine Linux install process which is quick and simple. Pick your keymap, hostname, network config, root password, users, and installation disk. Quick as a flash it's installed, reboot and we're in! Total time: less than 5 minutes. Impressive!

Oi, what about that 2T limit? And no mention of setting up ZFS yet!

Yep, no ZFS yet. I just needed to check the install actually worked OK.

So, now with the knowledge Alpine will install and boot fine, let's start again. Boot netboot.xyz, into Alpine install iso, run through the Root on ZFS with native Encryption Alpine Linux wiki article as a I guide (I don't actually want root on ZFS, but it is a helpful guide nonetheless) and... oh, it seems I can't create a partition to use the entire 4T of space, only 2T partitions and only 4 partitions in total... 25 years ago me knows what's going on here: we've got a MBR/DOS partition table. D'oh!
It seems AlphaVPS Storage VPS's don't boot UEFI so my previous Alpine install when setting up the disk just automatically created a dos table. (Alpha VPS Storage VPS's might boot with UEFI actually, I don't know, it might be messed up with using netboot.xyz for booting - I don't know, but for whatever reason I could not get anything to boot with efivars).

OK, no problem, I can just recreate a new gpt partition table, create my partitions and be done, right?
Well, yes, but also no. Creating boot and root partitions, mounting them and installing alpine to them all worked fine, but a lovely "YOU MAY NEED TO RECREATE THE MBR" (or words to that effect) error sat there, glaring at me. If this was an MBR disk it would be fine, I have done that hundreds of times before, back in the day, but it isn't an MBR drive, it's GPT - that's different. If we had UEFI it's easy: create an EFI partition, install something like rEFInd and run refind-install and it should work, but we don't have EFI, so not an option.
Suffice to say, any attempts to boot failed. I need to sort something out. Grub didn't seem to be happy, nor syslinux, which Alpine has some default configuration for. I could not work out why!

So how do we fix this?

Installing Alpine again, on a GPT partition table

After a bit of internet searching, there is a solution, one I suspect many linux distros perform automatically, but I'm not using just any distro, I'm using Alpine - if you want a lean system, this is the one, but be ready for some manual work!

The UEFI article on the Alpine wiki had some hints, under "BIOS-GPT layout", but it still isn't 100% clear, so here is my workthrough of what I did to get this working:

The drive basically needs a small unformatted, umounted, partition set to partition type ef02 or BIOS boot partition, on which the boot code can be installed, which then starts your primary bootloader, which in turn starts your OS.

My full process is as follows:

First: boot Alpine via netboot.xyz iso and run through the setup-alpine process, but Ctrl-C out of it when it asks what disk to install to.
Install some necessary tools and create some partitions.

$ apk add cfdisk gptfdisk e2fsprogs-extra
$ gdisk /dev/vda

### Create a new GPT partition table
gdisk> o

### Create a new BIOS Boot partition
gdisk> n
gdisk partition number> use the default, or whatever you like
gdisk first sector> leave default, press enter
gdisk last sector> +32M # 32 Megabyte partition
gdisk type> ef02 # BIOS boot partition

### Create a new EFI partition
gdisk> n
gdisk partition number> use the default, or whatever you like
gdisk first sector> leave default, press enter
gdisk last sector> +1G # 1 Gigabyte
gdisk type> ef00 # EFI system partition

### Create a root partition
gdisk> n
gdisk partition number> use the default, or whatever you like
gdisk first sector> leave default, press enter
gdisk last sector> +64G # 64 Gigabyte
gdisk type> 8300 # Linux filesystem

### Write changes to disk
gdisk> w
gdisk confirm> y

### Make sure Alpine can see the new partition structure
$ mdev -s

Now we need to format those partitions correctly (we ignore /dev/vda1, leave that unformatted) and mount them.

$ mkfs.vfat /dev/vda2
$ mkfs.ext4 /dev/vda3
$ mount -t ext4 /dev/vda3 /mnt # Root FS
$ mkdir /mnt/boot # It's an empty partition, so we need to create this directory
$ mount -t vfat /dev/vda2 /mnt/boot

I intend on using the remaining space as a ZFS partition when I have ZFS installed on the running system, but best to get the system running first I think.

If you haven't run through the setup-alpine process yet, do that now, and Ctrl-C when it asks about disks.

Install Alpine to the new mountpoint:

$ setup-disk /mnt

Install the bootloader

Now, the crucial bit - installing the bootloader. I chose Limine in the end as it was the most successful outcome for me - you may have a different experience.
Limine has a section in their USAGE.md that talks about how to install for BIOS/GPT

$ apk add limine
### Install to your ef02/BIOS boot partition i.e. /dev/vda1
$ limine bios-install /dev/vda 1 # the space is important!! Disk and partition index are separate variables
### It tells you to do this anyway, but copy the limine boot files to your boot partition
$ cp /usr/share/limine/* /mnt/boot/

Now we just need a config file. There's a load of documentation on this, but my config file looks a little like the below:


## /mnt/boot/limine.conf (will be /boot/limine.conf once running on the installed system)
timeout: 4

/Alpine Linux
    protocol: linux
    kernel_path: boot():/vmlinuz-lts
    module_path: boot():/initramfs-lts
    cmdline: root=UUID=XXXX modules=sd-mod,usb-storage,ext4 nomodeset quiet rootfstype=ext4
    comment: Boot Alpine Linux

Replace XXXX with the UUID of your root partition. To make it easier, I just took the whole line from the generated /mnt/boot/extlinux.conf file that Alpine made during setup-disk and replaced "APPEND" with "cmdline:" after dumping the contents into the file as below:

$ grep APPEND /mnt/boot/extlinux.conf >> /mnt/boot/limine.conf
## Then edit /mnt/boot/limine.conf and change APPEND to "cmdline:"

Finally, if all comes back OK... REBOOT!

If all goes well, we should be in a brand spanking new Alpine Linux installation!

Setting up ZFS

Could not be easier (except if we had installed FreeBSD of course!)

Install and Enable/Start ZFS services

$ apk add zfs
$ rc-update add zfs-import # Which allows finding ZFS pools
$ rc-update add zfs-mount # Which allows mounting ZFS pools
$ rc-service zfs-import start
$ rc-service zfs-mount start

# You might need to get zfs modules going before the last 2 commands
$ modprobe zfs

Create a new empty partition using whatever tool you like that speaks GPT tables: gdisk, cfdisk, etc. and use the whole space if you want, then create the pool

$ zpool create tank /dev/vda4

And we're done! Create your datasets using standard zfs utilities and be happy!

ZFS Utilities only run as root.

In Alpine, ZFS utilities i.e. zfs list to show datasets, can only be run as root. Whereas there are times when you may want a standard user to have permission to do so, i.e. on a zfs recv. I'm sure there's a better way than this, but changing permissions on /dev/zfs allows for this.

$ chmod 0666 /dev/zfs

Of course, ZFS's own permissions still prevent a standard user doing nasty stuff, so we should be fine here.

Final note

This took much longer than I wanted it to, but I'm satisfied with the results. I totally did not expect to be dealing with MBR/BIOS/DOS partitions in 2026, but maybe they are still out there in some scenarios.

I've remembered/learned a lot from this, and actually I ended up quite liking Alpine Linux. I'm using it as a daily driver on my laptop now to see how we do! I may write about that later.

Oh... and enable your firewall!

$ apk add ufw
$ ufw enable

Be Good!