{"record":{"id":"62b51ea44ed560be","repo":"rancher/rancher","slug":"invalid-clientid","errorCode":null,"errorMessage":"invalid clientId","messagePattern":"invalid clientId","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/api/norman/customization/aks/handler.go","lineNumber":334,"sourceCode":"\nfunc (h *handler) getCredentialsFromBody(req *http.Request, cap *Capabilities) (int, error) {\n\traw, err := io.ReadAll(req.Body)\n\tif err != nil {\n\t\treturn http.StatusBadRequest, fmt.Errorf(\"cannot read request body: %v\", err)\n\t}\n\n\tif err = json.Unmarshal(raw, &cap); err != nil {\n\t\treturn http.StatusBadRequest, fmt.Errorf(\"cannot parse request body: %v\", err)\n\t}\n\n\tif cap.SubscriptionID == \"\" {\n\t\treturn http.StatusBadRequest, fmt.Errorf(\"invalid subscriptionId\")\n\t}\n\tif cap.TenantID == \"\" {\n\t\treturn http.StatusBadRequest, fmt.Errorf(\"invalid tenantId\")\n\t}\n\tif cap.ClientID == \"\" {\n\t\treturn http.StatusBadRequest, fmt.Errorf(\"invalid clientId\")\n\t}\n\tif cap.ClientSecret == \"\" {\n\t\treturn http.StatusBadRequest, fmt.Errorf(\"invalid clientSecret\")\n\t}\n\n\tclientEnvironment := \"\"\n\tif cap.Environment != \"\" {\n\t\tclientEnvironment = cap.Environment\n\t}\n\t_, azureEnvironment := GetEnvironment(clientEnvironment)\n\n\tif cap.BaseURL == \"\" {\n\t\tcap.BaseURL = azureEnvironment.ResourceManagerEndpoint\n\t}\n\tif cap.AuthBaseURL == \"\" {\n\t\tcap.AuthBaseURL = azureEnvironment.ActiveDirectoryEndpoint\n\t}\n","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/rancher/rancher/blob/932558d4e68565aff2d2f36e89ec4a391b06e7c5/pkg/api/norman/customization/aks/handler.go#L316-L352","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconst body = { subscriptionId, tenantId, clientSecret };\n// after\nconst body = { subscriptionId, tenantId, clientId, clientSecret };","handlingStrategy":"validation","validationCode":"if (!isGuid(body.clientId)) throw new Error('clientId (app registration appId GUID) is required');","typeGuard":"function hasClientId(b) { return /^[0-9a-f-]{36}$/i.test(b?.clientId || ''); }","tryCatchPattern":"if (!hasClientId(body)) { flagField('clientId'); return; }\nconst resp = await post(listEndpoint, body);","preventionTips":["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"],"tags":["aks","azure","validation","service-principal","http-400"],"backgroundTag":null,"analyzedSha":"932558d4e68565aff2d2f36e89ec4a391b06e7c5","analyzedAt":"2026-08-16T04:37:02.125Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}