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
- Include clientId (the app registration Application ID GUID, not the service principal objectId) in the payload
- Fetch it from Azure: 'az ad sp show --id <name> --query appId -o tsv'
- 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
- Store the appId (not the service principal objectId) as clientId
- Capture appId + secret together at creation time in your secret manager
- Guard forms so a cleared field blocks submission
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
- must provide clientSecret
- invalid subscriptionId
- invalid tenantId
- invalid clientSecret
- region is required
AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16).
Data as JSON: /api/errors/62b51ea44ed560be.
Report an issue: GitHub.