rancher/rancher · error

invalid clientId

Error message

invalid clientId

What it means

Third field check in getCredentialsFromBody (handler.go:333): subscriptionId and tenantId passed but clientId is an empty string, returning 400 'invalid clientId'. The clientId is the Azure app registration's application (client) ID that must exist as a service principal in the tenant.

Source

Thrown at pkg/api/norman/customization/aks/handler.go:334

func (h *handler) getCredentialsFromBody(req *http.Request, cap *Capabilities) (int, error) {
	raw, err := io.ReadAll(req.Body)
	if err != nil {
		return http.StatusBadRequest, fmt.Errorf("cannot read request body: %v", err)
	}

	if err = json.Unmarshal(raw, &cap); err != nil {
		return http.StatusBadRequest, fmt.Errorf("cannot parse request body: %v", err)
	}

	if cap.SubscriptionID == "" {
		return http.StatusBadRequest, fmt.Errorf("invalid subscriptionId")
	}
	if cap.TenantID == "" {
		return http.StatusBadRequest, fmt.Errorf("invalid tenantId")
	}
	if cap.ClientID == "" {
		return http.StatusBadRequest, fmt.Errorf("invalid clientId")
	}
	if cap.ClientSecret == "" {
		return http.StatusBadRequest, fmt.Errorf("invalid clientSecret")
	}

	clientEnvironment := ""
	if cap.Environment != "" {
		clientEnvironment = cap.Environment
	}
	_, azureEnvironment := GetEnvironment(clientEnvironment)

	if cap.BaseURL == "" {
		cap.BaseURL = azureEnvironment.ResourceManagerEndpoint
	}
	if cap.AuthBaseURL == "" {
		cap.AuthBaseURL = azureEnvironment.ActiveDirectoryEndpoint
	}

View on GitHub (pinned to 932558d4e6)

Solutions

  1. Include clientId (the app registration Application ID GUID, not the service principal objectId) in the payload
  2. Fetch it from Azure: 'az ad sp show --id <name> --query appId -o tsv'
  3. Check for empty-string env var interpolation in automation

Example fix

// before
const body = { subscriptionId, tenantId, clientSecret };
// after
const body = { subscriptionId, tenantId, clientId, clientSecret };
Defensive patterns

Strategy: validation

Validate before calling

if (!isGuid(body.clientId)) throw new Error('clientId (app registration appId GUID) is required');

Type guard

function hasClientId(b) { return /^[0-9a-f-]{36}$/i.test(b?.clientId || ''); }

Try / catch

if (!hasClientId(body)) { flagField('clientId'); return; }
const resp = await post(listEndpoint, body);

Prevention

When it happens

Trigger: Inline credential payload missing the clientId key or containing clientId:"" - e.g. only the secret was refreshed in the UI state and the app id field was cleared.

Common situations: Form state partially reset after an edit; scripts that populate clientId from an unset environment variable; pasting the objectId of the service principal instead of the appId and then deleting it when it fails elsewhere.

Related errors


AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16). Data as JSON: /api/errors/62b51ea44ed560be. Report an issue: GitHub.