Netflix/chaosmonkey · error
alternateAccountID called with forbidden arg: %s
Error message
alternateAccountID called with forbidden arg: %s
What it means
alternateAccountID() is a fallback for accounts without their own accountId: it maps names containing "test" to the "test" account and everything else to "prod". This guard rejects calls with "prod" or "test" themselves, because recursing on them would loop forever (AccountID("prod") -> no accountId -> alternateAccountID("prod") -> ...).
Source
Thrown at spinnaker/spinnaker.go:224
}
// Some backends may not have associated account ids
if info.AccountID == "" {
return s.alternateAccountID(name)
}
return info.AccountID, nil
}
// alternateAccountID returns an account ID for accounts that don't have their
// own ids.
func (s Spinnaker) alternateAccountID(name string) (string, error) {
// Sanity check: this should never be called with "prod" or "test" as an
// argument, since this would result in infinite recursion
if name == "prod" || name == "test" {
return "", fmt.Errorf("alternateAccountID called with forbidden arg: %s", name)
}
// Heuristic: if account name has "test" in the name, we return the "test"
// account id, otherwise with we use the "prod" account id
if strings.Contains(name, "test") {
return s.AccountID("test")
}
return s.AccountID("prod")
}
// Apps implements deploy.Deployment.Apps
func (s Spinnaker) Apps(c chan<- *D.App, appNames []string) {
// Close the channel we're done
defer close(c)
for _, appName := range appNames {
app, err := s.GetApp(appName)View on GitHub (pinned to eaa28fb761)
Solutions
- Inspect the raw response of GET <endpoint>/accounts/prod — if accountId is genuinely missing, fix the Spinnaker/clouddriver deployment
- Check the API URL construction (accountURL) and the Spinnaker version compatibility; upgrade chaosmonkey or clouddriver as needed
- As a workaround, run against a Spinnaker instance that returns accountId for the prod/test accounts
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify prod/test accounts return an accountId before running:
var info struct{ AccountID string `json:"accountId"` }
// GET <endpoint>/accounts/prod, unmarshal; if AccountID == "", the fallback will trip Try / catch
id, err := spin.AccountID("prod")
if err != nil {
if strings.Contains(err.Error(), "alternateAccountID called with forbidden arg") {
log.Printf("Spinnaker not returning accountId for prod/test: %v", err)
}
return err
} Prevention
- Check after Spinnaker upgrades that /accounts/prod and /accounts/test still include accountId
- Use clouddriver versions compatible with this chaosmonkey release
- Alert on this error since it indicates backend schema drift
- Test account-ID resolution in a pre-flight check
When it happens
Trigger: AccountID("prod") or AccountID("test") succeeds at HTTP level but the response JSON has an empty accountId field, causing the fallback alternateAccountID("prod")/alternateAccountID("test") to be invoked, which immediately fails with this error.
Common situations: Spinnaker/clouddriver version change where the prod/test accounts stop returning an accountId field; a misbehaving backend returning 200 with empty bodies; querying an endpoint that proxies but does not enrich account data.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- info.Error
- no cloudProvider field in response body
- unexpected response code: %d, body: %s
- unexpected response code (%d) from %s
- retrieve cloud provider failed
AI-assisted analysis of Netflix/chaosmonkey@eaa28fb761 (2026-09-03).
Data as JSON: /api/errors/da1e10366cdda80d.
Report an issue: GitHub.