VCF 9.1 password rules: why one lab password cannot work everywhere (and NSX forbids full stops)

vCenter root wants 15 to 20 characters, SDDC Manager more than 13, and NSX bans most punctuation including the full stop. Pick a password NSX accepts and the rest follow.

Pick the password that NSX will accept and every other component follows automatically. NSX has the strictest rules in the stack: 15 to 20 characters, and none of {}[]()/\'"`~,;:.<>. That ban includes the full stop, which quietly disqualifies most people’s standard lab password. The reverse does not hold, so validating against vCenter or SDDC Manager first tells you nothing.

The three rules that collide

vCenter root must be 15 to 20 characters. Too short and validation fails with VC_ROOT_PASSWORD_LENGTH.

SDDC Manager local user needs more than 13 characters. Too short gives you SHORT_LOCAL_USER_PASSWORD.

NSX wants the same 15 to 20 length and restricts the character set. Letters and digits are fine. Of the punctuation, only @ ! # $ % ? ^ * were accepted here. Everything in {}[]()/\'"`~,;:.<> was rejected.

That last rule is the one that catches people, because a password can satisfy every length requirement in the stack and still be refused by NSX for containing a single ..

Why NSX first is the shortcut

NSX’s rules are a strict subset of everyone else’s. Anything NSX accepts is automatically acceptable to vCenter, SDDC Manager and the rest of the fleet. Anything the others accept may still fail NSX.

So generate against the NSX rules once, rather than discovering the constraint component by component several minutes into a failed deployment.

Your ESXi hosts and your VCF appliances cannot share a password

The nested ESXi hosts keep whatever password they were installed with, and ESXi does not enforce the 15 character rule. The VCF appliances do enforce it.

If your existing lab password is 13 characters, as mine was, it stays valid on the hosts and is rejected by the appliances. These end up as two genuinely different credentials. That is a consequence of the 9.1 length rule, not a security design choice, and it is worth writing down somewhere before you forget which is which.

Check before you submit, not after

Password rejections surface during spec validation, which is minutes into a submission and well after you have stopped paying attention.

It is worth failing early and locally instead. My spec builder refuses to build at all when a password would be rejected, and names the specific rule it would have broken, rather than letting the API discover it later.

One practical note if you script this: check the characters programmatically without printing the value. It is easy to write a “helpful” diagnostic that echoes the password into a log or a terminal transcript.

Verified, and what is inference

Verified here: the VC_ROOT_PASSWORD_LENGTH (15 to 20) and SHORT_LOCAL_USER_PASSWORD (more than 13) codes from live validation against POST /v1/sddcs/validations on 9.1.0, that a 13 character password was accepted by ESXi and rejected by the appliances, and that both a VCF_APPLIANCE_PASSWORD and a NESTED_ESXI_PASSWORD containing . failed the NSX character rule.

Corroborating, from community guidance for 9.1: deployment guides recommend at least 15 characters for the whole deployment with a small allowed set of special characters. Published lists differ slightly at the edges from what I observed (& appears in some, ? in mine), so treat the exact allowed set as approximate and the exclusion of ordinary punctuation like . as the reliable part.

Inference: that NSX’s rules are a strict subset of every other component’s. It held for every component in this deployment, but I validated against the fleet I built, not against every possible VCF component.


The wider story of building this lab, including how an agent drove most of it, is in I Let Claude Code Deploy My VCF 9.1 Home Lab, and This Is What Happened.