{"record":{"id":"1ff98ee16c5d8a07","repo":"netbirdio/netbird","slug":"password-cannot-be-empty","errorCode":null,"errorMessage":"password cannot be empty","messagePattern":"password cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/cmd/expose.go","lineNumber":127,"sourceCode":"\n\tif !isProtocolValid(exposeProtocol) {\n\t\treturn 0, fmt.Errorf(\"unsupported protocol %q: must be http, https, tcp, udp, or tls\", exposeProtocol)\n\t}\n\n\tif isClusterProtocol(exposeProtocol) {\n\t\tif exposePin != \"\" || exposePassword != \"\" || len(exposeUserGroups) > 0 {\n\t\t\treturn 0, fmt.Errorf(\"auth flags (--with-pin, --with-password, --with-user-groups) are not supported for %s protocol\", exposeProtocol)\n\t\t}\n\t} else if cmd.Flags().Changed(\"with-external-port\") {\n\t\treturn 0, fmt.Errorf(\"--with-external-port is not supported for %s protocol\", exposeProtocol)\n\t}\n\n\tif exposePin != \"\" && !pinRegexp.MatchString(exposePin) {\n\t\treturn 0, fmt.Errorf(\"invalid pin: must be exactly 6 digits\")\n\t}\n\n\tif cmd.Flags().Changed(\"with-password\") && exposePassword == \"\" {\n\t\treturn 0, fmt.Errorf(\"password cannot be empty\")\n\t}\n\n\tif cmd.Flags().Changed(\"with-user-groups\") && len(exposeUserGroups) == 0 {\n\t\treturn 0, fmt.Errorf(\"user groups cannot be empty\")\n\t}\n\n\treturn port, nil\n}\n\nfunc isProtocolValid(exposeProtocol string) bool {\n\tswitch strings.ToLower(exposeProtocol) {\n\tcase \"http\", \"https\", \"tcp\", \"udp\", \"tls\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/expose.go#L109-L145","documentation":"--with-password was explicitly present on the command line (cmd.Flags().Changed(\"with-password\") is true) but its value is the empty string. NetBird distinguishes 'flag absent' from 'flag set to empty' and rejects the latter, since an empty password would silently expose the service unprotected.","triggerScenarios":"`--with-password=` or `--with-password \"\"`, most commonly an unset or empty environment variable expanded by a script (e.g. `--with-password \"$SECRET\"` with SECRET unset).","commonSituations":"CI pipelines and deployment scripts passing an unset secret variable; templating systems (YAML/JSON env injection) rendering an empty string.","solutions":["Provide a real password: `--with-password my-secret`","Fix the source of the empty value: verify the variable/secret reference (`echo \"${SECRET:?SECRET not set}\"`) before building the command"],"exampleFix":"# before\nnetbird expose --with-password \"$SECRET\" 8080   # SECRET unset\n\n# after\nexport SECRET=my-secret\nnetbird expose --with-password \"$SECRET\" 8080","handlingStrategy":"validation","validationCode":"if passwordFlagSet && password == \"\" {\n\tlog.Fatal(\"--with-password was set but empty; check the variable feeding it (unset secret?)\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use ${VAR:?message} for secrets so an unset variable aborts the script instead of the CLI","Only pass --with-password when a non-empty value is actually available","Remember the CLI distinguishes 'flag absent' from 'flag set to empty' and rejects the latter"],"tags":["cli","validation","password","empty-value","netbird-cli"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}