Troubleshooting
Missing Environment Variables
If the server exits with a missing variable error, set all required values:
VCFA_HOST=...
VCFA_USERNAME=...
VCFA_ORGANIZATION=...
VCFA_PASSWORD=...401 Unauthorized At Login
The session request sends Basic auth as {VCFA_USERNAME}@{VCFA_ORGANIZATION}. If credentials are correct but the login still returns 401:
VCFA_ORGANIZATIONmust be the organization name (the tenant URL slug, for example the<orgName>inhttps://<host>/tenant/<orgName>), not its display name.- Provider/system administrator accounts must set
VCFA_ORGANIZATION=system. That routes the login to/cloudapi/1.0.0/sessions/provider; the tenant/sessionsendpoint rejects provider accounts with 401 regardless of password. - The server auto-negotiates the VCF Cloud API version (
9.1.0on VCF Automation 9.1,9.0.0otherwise) viaGET /api/versions. If negotiation misbehaves against an unusual target, pin it withVCFA_TARGET_PLATFORM=vcfa9.1orvcfa9.0.
A 403 on the default vcfa platform is never a login problem either: a revoked or invalid session answers 401, so a 403 is a denial and is reported directly rather than costing a re-login and a retry. Its WWW-Authenticate challenge is deliberately not consulted — project-service sends one on a 403 that is a genuine denial.
For VCFA_TARGET_PLATFORM=vra8 the login is the vRA 8 bearer-token flow, a vIDM CSP login followed by a refresh-token exchange at /iaas/api/login, rather than the Cloud API session. If it fails:
- A
400or401from/csp/gateway/am/api/loginmeans the vIDM credentials or domain are wrong.VCFA_USERNAMEandVCFA_PASSWORDare the Workspace ONE Access credentials, andVCFA_ORGANIZATIONmust be the domain shown on that login page, for exampleSystem Domainfor local users. A VCF organization name orsystemis rejected there. - The domain must reach the server as the exact string, spaces included. In an MCP client's JSON
envblock that is simply"VCFA_ORGANIZATION": "System Domain"— quotes written inside the value become part of it and the CSP login rejects them with400. On a command line the value needs shell quoting (VCFA_ORGANIZATION="System Domain"), or the shell treats the word after the space as the command. Surrounding whitespace is trimmed before the login. - A
401from/vco/apiafter a successful login is treated as an expired token: the server renews it (exchanging the cached refresh token, or repeating the CSP login if that is rejected) and retries once before surfacing the error. - A
403from/vco/apiis not a login problem. Unless it carries aWWW-Authenticatechallenge, it is reported directly as an authorization result: the vIDM user has no permission for that vRO object or operation. - A redirect on either login endpoint is reported as a login failure naming the host it points at, and is deliberately not followed — the request body carries the credentials. Point
VCFA_HOSTat the appliance's API endpoint rather than at an SSO portal or a redirecting load balancer.
Provider Session Cannot Read The Automation Services
VCFA_ORGANIZATION=system authenticates a provider/system administrator, and vRO works normally — but the VCF Automation services are tenant-scoped and a provider identity has no auth-context in that stack. Two signatures, both fixed the same way:
403 Forbidden — GET /projectswith an empty body, carrying a hint that namesVCFA_ORGANIZATION.list-projectsandget-projectare the tools that reach project-service.500 Internal Server Errorfrom the catalog, deployment, template, or subscription tools. Those services turn the refusal into a server error rather than passing the403through; on VCF Automation 9.1 the blueprint-service body names the cause outright, a refusedGET .../rbac-service/api/auth-context. The same hint is attached whenever the session is a provider one.
Set VCFA_ORGANIZATION to the tenant organization's name (its URL slug) and restart the server. vRO (/vco/api) works on either session, so a configuration that only drives workflows, actions, configuration elements, resources, and packages can stay on the provider account.
TLS Errors In Lab Environments
For lab systems with self-signed certificates, set:
VCFA_IGNORE_TLS=trueUse this only when you accept the TLS risk.
Workflow Run Failures
Prefer run-workflow-and-wait with confirm: true during development after the target workflow and inputs are verified. It validates input names and types against get-workflow, waits for completion, and returns failure context when available.
If a workflow was started asynchronously, use:
list-workflow-executionsget-workflow-executionget-workflow-execution-logs
get-workflow-execution-logs reads the execution syslogs stream, which is where vRO exposes workflow token messages such as System.log, System.debug, System.warn, and System.error. Use level: "error" to show only error entries, or provide fileName to export the filtered logs as .json or .txt.
vRA/vRO 8 Mode
Set VCFA_TARGET_PLATFORM=vra8 for vRA/vRO 8.12+. The server authenticates with the vRA 8 bearer-token flow described above and supports the full vRO /vco/api surface plus the read paths of the catalog, deployment, template, project, subscription, and event-topic tools. Template, subscription and deployment writes are supported here (verified under VCFO-070 and VCFO-088). One thing still returns an unsupported-mode message in this mode:
export-configuration-file, because vRA 8 serves a configuration element as JSON only and rejects the artifact request with406. Read it withget-configuration, or add it to the project package withadd-configuration-to-project-packageand runexport-project-package.prepare-artifact-promotionwithbackup.enabledfor a configuration artifact reportsBackup skipped:with the same pointer and still returns the preflight report and import recommendation.
A 400 in this mode used to arrive with no usable detail: the vRA 8 gateway answers a rejected /vco/api request with a styled HTML page whose only diagnostic content is the status code and reason, buried past a stylesheet, and these responses arrive over HTTP/2, which carries no reason phrase. Such a body is now summarized as [HTML body: 400 Bad Request — no further detail] instead of an excerpt of CSS, and every error message fills in the standard reason phrase when the response carries none, so the status line reads 400 Bad Request rather than a bare 400.
External vRO Appliance
Three signatures point at the vRO host rather than at credentials:
- Every vRO tool fails with
403 Forbiddenand[HTML body: 403 … — no further detail]while the catalog, deployment, template, and project tools work./vco/apiis reaching the Automation appliance's embedded orchestrator, but the organization's vRO runs on an external appliance. A genuine vRO refusal is a401with an empty body; the HTML page is the appliance itself refusing the tenant, so no re-login is attempted and the error carries a hint naming this variable. The hint appears only for/vco/api, the only thing the variable moves — an HTML403from the catalog, deployment, template, or project tools is a different problem. Set the external appliance as the vRO host and restart the server:
VCFA_HOST=vcfa.example.com
VCFA_VRO_HOST=vro.example.comRequest to vro.example.com failed: ENOTFOUND(orECONNREFUSED, or a TLS error code). The named host is the one that failed — a typo inVCFA_VRO_HOST, or a host the server cannot reach. Transport failures name the host they were addressed to, for either variable.302 Found — GET /workflows … on vro.example.comwithHint: the API answered with a redirect to …. The host answers the API path with a redirect to a UI or SSO page, so it is a load balancer, a portal, or the wrong appliance. Redirects to a JSON API request are deliberately not followed; the hint names the target and the variable to check.VCF authentication failed: 302 Found: the login endpoint answered with a redirect to ui.example.com …. The same cause one step earlier, at login:VCFA_HOSTaddresses something that redirects/cloudapi/1.0.0/sessionsrather than serving it. The external vRO redirects that endpoint, which is why it cannot be used asVCFA_HOST— set it onVCFA_VRO_HOSTand pointVCFA_HOSTat the Automation appliance. The login POST does not follow the redirect (itsAuthorizationheader carries the credentials), and the message names the target's host, never its query.
At startup the server logs [vcfa-server] VCFA_VRO_HOST=…: vRO API requests (/vco/api) are sent to this host; authentication and the Automation services use VCFA_HOST=…, and while the two hosts differ every [vro-client] log line and every vRO API error ends with on <host>. Both variables reject a value carrying a URL scheme at startup; VCFA_VRO_HOST also rejects a path.
Artifact Import Failures
Run the matching preflight tool first. Common issues include:
- malformed ZIP archive
- missing
workflow-infoorworkflow-content - wrong workflow-content encoding
- bad parameter or binding references
- unsafe file name or path
- package contents that include malformed nested artifacts
409 Conflict On An Element Delete
delete-workflow, delete-action, and delete-configuration can answer 409 with vRO reporting the element as in use. Right after delete-package with deleteContents: false, that is almost always a transient release race rather than a genuine reference: the package release takes a couple of seconds to settle, and the same delete then succeeds.
Retry the plain delete first. Only if the conflict persists should you pass force: true, which sends vRO's own ?force=true and skips the reference check — it does not establish that nothing references the element, so confirm the impact before using it. The error carries this hint for the same reason.
If the conflict survives a force, the element genuinely has live references. Find them before deleting: list the package contents, or check the workflows and actions in the same category.
406 On A Configuration Element Export
export-configuration-file answers 406 Not Acceptable because no vRO tested, on either platform, serves a single configuration element as a .vsoconf artifact. application/zip, application/vcoobject+zip, and application/octet-stream are all refused, while */* returns the element as JSON. Workflow, action, and package exports succeed on those same hosts, so the refusal is specific to configuration elements rather than to the host or the identity.
In vra8 mode the request is refused pre-emptively. On every other platform it is sent and the 406 is reported with the same guidance rather than as the server's HTML error page.
Two routes work instead:
get-configurationto read the element, including its attribute values.add-configuration-to-project-packagefollowed byexport-project-packageto get it into a file.
prepare-artifact-promotion reports a configuration backup as skipped in vra8 mode for the same reason and still returns its report. On other platforms that backup attempts the export and surfaces the refusal.
Catalog Or Template Ambiguity
Catalog items, templates, and deployments can be project-scoped. If a search returns no match or several plausible matches, inspect with get-catalog-item, get-template, or get-deployment before creating or updating anything.
GitHub Pages
After merging the docs workflow, set repository Pages source to GitHub Actions in GitHub repository settings. The workflow publishes the VitePress build output from docs/.vitepress/dist.