Netflix/chaosmonkey · error

info.Error

Error message

info.Error

What it means

AccountID() fetches the AWS account ID for a named Spinnaker account. When the Spinnaker API returns a non-200 status, the response body may carry an "error" field; this error re-surfaces that server-provided message verbatim via errors.New(info.Error).

Source

Thrown at spinnaker/spinnaker.go:205

		return "", errors.Wrapf(err, "failed to read body from url %s", url)
	}

	var info struct {
		AccountID string `json:"accountId"`
		Error     string `json:"error"`
	}

	err = json.Unmarshal(body, &info)
	if err != nil {
		return "", errors.Wrapf(err, "could not parse body of %s as json, body: %s, error", url, body)
	}

	if resp.StatusCode != http.StatusOK {
		if info.Error == "" {
			return "", errors.Errorf("%s returned unexpected status code: %d, body: %s", url, resp.StatusCode, body)
		}

		return "", errors.New(info.Error)
	}

	// 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" {

View on GitHub (pinned to eaa28fb761)

Solutions

  1. Check the error text returned: it is the message Spinnaker itself sent, which usually names the real problem (unknown account, auth denied, etc.)
  2. Verify the account name exists in Spinnaker (GET /accounts) and matches exactly (case-sensitive)
  3. Confirm the TLS client cert is accepted by the Spinnaker endpoint (401/403 usually means cert auth failed)
  4. Inspect Spinnaker/clouddriver logs for the corresponding request error
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check that the account exists before calling AccountID:
resp, err := http.Get(endpoint + "/accounts")
// ... decode and ensure the desired account name is present in the list

Try / catch

id, err := spin.AccountID("prod")
if err != nil {
	// err text is Spinnaker's own "error" field; log it and skip/abort gracefully
	log.Printf("AccountID failed: %v", err)
	return err
}

Prevention

When it happens

Trigger: Calling AccountID(name) (directly or via alternateAccountID) and the Spinnaker accounts endpoint replies with a status code other than 200 AND a JSON body containing a non-empty "error" field.

Common situations: Spinnake clouddriver returning 404 for an unknown account name; auth/TLS failures producing 401/403; the Spinnaker backend reporting its own internal errors with an error payload.

Related errors


AI-assisted analysis of Netflix/chaosmonkey@eaa28fb761 (2026-09-03). Data as JSON: /api/errors/9a6046a291ea3445. Report an issue: GitHub.