Proxmox cloud-init only creating default user is the image’s default user overriding your UI setting. You set a custom user in the Cloud-Init tab, but the VM still boots with the image’s baked-in default. Here’s the exact config that forces your user.

Why the UI setting gets ignored
Cloud images ship with a default user (like ubuntu or debian) and a cloud-init config that creates it on first boot. Proxmox passes your settings via the NoCloud datasource, but the image’s own cloud-init config can take precedence. The UI sets ciuser, but if the image has users: in its /etc/cloud/cloud.cfg, that default user still gets created. Your custom user might be added, but the default remains — and if you set a password for the default user, it can lock you out.
The fix: override with a snippet
Stop relying on the UI alone. Create a cloud-init snippet that explicitly defines your user and disables the default.
- Enable snippets on a storage (see Proxmox snippets feature).
- Create a file
user-data.yamlwith:
#cloud-config
users:
- name: myuser
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- ssh-rsa AAAAB3...
lock_passwd: true
disable_root: false
- Upload it to the snippets storage.
- In the VM’s Cloud-Init tab, set
User datatosnippets:user-data.yaml. - Regenerate the cloud-init drive and reboot.
Now your user is the only one created. The image’s default user config gets overridden because your snippet is merged later.

What if you still see the default user?
Check the image’s /etc/cloud/cloud.cfg. Some images have users: [default] hardcoded. You can remove it by adding this to your snippet:
users:
- default
- name: myuser
...
But that’s hacky. Better to use a cloud image that respects the datasource, like the official Ubuntu cloud images. They don’t hardcode users.
Also, make sure you didn’t set a password in the UI for the default user. That can re-enable it. Leave the password field empty and use SSH keys.
My take
This is annoying. The UI implies it works, but the image wins. I’d just always use a snippet for user data. It’s explicit and you can version it. And don’t bother with the default user — delete it from the image or ignore it. If you need a quick test, use cloud-init clean --logs and reboot to re-run everything.