{"record":{"id":"e8f9e59c4be35ab1","repo":"weaviate/weaviate","slug":"failed-to-decode-auth-broker-response-w","errorCode":null,"errorMessage":"failed to decode auth broker response: %w","messagePattern":"failed to decode auth broker response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"usecases/modulecomponents/awscommon/auth_broker.go","lineNumber":171,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: %w\", ErrRetryableAuthBroker, err)\n\t}\n\tdefer func() {\n\t\t_, _ = io.Copy(io.Discard, resp.Body)\n\t\tresp.Body.Close()\n\t}()\n\n\tif resp.StatusCode >= 500 || resp.StatusCode == http.StatusTooManyRequests {\n\t\treturn nil, fmt.Errorf(\"%w: auth broker returned status %d\", ErrRetryableAuthBroker, resp.StatusCode)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"auth broker returned non-200 status: %d\", resp.StatusCode)\n\t}\n\n\tvar creds AuthBrokerCredentialValue\n\tif err := json.NewDecoder(resp.Body).Decode(&creds); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode auth broker response: %w\", err)\n\t}\n\n\tif creds.AccessKeyID == \"\" || creds.SecretAccessKey == \"\" || creds.SessionToken == \"\" || creds.Expiration.IsZero() {\n\t\treturn nil, errors.New(\"auth broker response missing required fields (access_key_id, secret_access_key, session_token, expiration)\")\n\t}\n\n\treturn &creds, nil\n}\n\nfunc (b *AuthBrokerCredentials) readIdentityToken() (string, error) {\n\ttok, err := os.ReadFile(b.identityTokenPath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to read web identity token from %q: %w\", b.identityTokenPath, err)\n\t}\n\t// An empty file most likely means we caught kubelet mid-rotation. Fail\n\t// clearly at this layer rather than sending \"Authorization: Bearer \" to\n\t// the broker and getting an opaque 401 back.\n\ttrimmed := strings.TrimSpace(string(tok))","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/usecases/modulecomponents/awscommon/auth_broker.go#L153-L189","documentation":"After a 200 response, fetchCredentials decodes the body into AuthBrokerCredentialValue. If the JSON is malformed or truncated, the decode error is wrapped with this message, so the failure is in the broker response payload, not the HTTP layer.","triggerScenarios":"JSON decoding of resp.Body fails — empty body, HTML error page behind a proxy returning 200, or truncated response.","commonSituations":"Reverse proxy/ingress intercepts and returns a 200 HTML login page; broker version returns a different JSON schema; network truncation of a partial response.","solutions":["Inspect the raw broker response body for unexpected HTML or schema drift","Check any proxy/ingress between Weaviate and the broker for interference","Verify broker version compatibility with AuthBrokerCredentialValue field names"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify the broker returns JSON, not an HTML page behind a proxy\nresp, _ := http.Get(brokerURL)\nct := resp.Header.Get(\"Content-Type\")\nif !strings.Contains(ct, \"application/json\") {\n    return fmt.Errorf(\"broker returned non-JSON content type %q\", ct)\n}","typeGuard":null,"tryCatchPattern":"creds, err := fetchCredentials(ctx)\nif err != nil && strings.Contains(err.Error(), \"failed to decode\") {\n    // log the raw response body for diagnosis, then fail\n    return fmt.Errorf(\"broker payload invalid: %w\", err)\n}","preventionTips":["Check for proxies/ingress that can return 200 with HTML bodies","Pin compatible broker versions and test the response schema in CI","Monitor Content-Type of broker responses"],"tags":["aws","auth-broker","json","decode-error"],"backgroundTag":"json-decode-failed","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}