Netflix/chaosmonkey · error
unexpected response code: %d, body: %s
Error message
unexpected response code: %d, body: %s
What it means
Returned by Terminator.Execute when Spinnaker responds to the termination POST with a status other than 200; the body of the non-OK response is read and included to show why Spinnaker rejected the terminate request.
Source
Thrown at spinnaker/terminator.go:99
payload := killJSONPayload(ins, otherID, s.user)
resp, err := s.client.Post(url, "application/json", bytes.NewReader(payload))
if err != nil {
return errors.Wrap(err, fmt.Sprintf("POST to %s failed, (body '%s')", url, string(payload)))
}
defer func() {
if cerr := resp.Body.Close(); cerr != nil && err == nil {
err = errors.Wrap(cerr, fmt.Sprintf("failed to close response body of %s", url))
}
}()
if resp.StatusCode != http.StatusOK {
log.Printf("Unexpected response: %d", resp.StatusCode)
contents, err := ioutil.ReadAll(resp.Body)
if err != nil {
return errors.Wrap(err, "failed to read response body")
}
return fmt.Errorf("unexpected response code: %d, body: %s", resp.StatusCode, string(contents))
}
return nil
}
// killJsonPayload generates the JSON request body for terminating an instance
// otherID is an optional second instance ID, as some backends may have a second
// identifer.
func killJSONPayload(ins chaosmonkey.Instance, otherID string, spinnakerUser string) []byte {
var desc string
if otherID != "" {
desc = fmt.Sprintf("Chaos Monkey terminate instance: %s %s (%s, %s, %s)", ins.ID(), otherID, ins.AccountName(), ins.RegionName(), ins.ASGName())
} else {
desc = fmt.Sprintf("Chaos Monkey terminate instance: %s (%s, %s, %s)", ins.ID(), ins.AccountName(), ins.RegionName(), ins.ASGName())
}
p := killPayload{
Application: ins.AppName(),View on GitHub (pinned to eaa28fb761)
Solutions
- Log/inspect the returned body to see Spinnaker's error detail
- Verify Spinnaker API URL and authentication credentials
- Check that the instance ID/account/region in the kill payload is valid
- Check Spinnaker server health if 5xx persists
Example fix
// before
return fmt.Errorf("unexpected response code: %d, body: %s", resp.StatusCode, string(contents))
// after
if resp.StatusCode == http.StatusUnauthorized {
return fmt.Errorf("spinnaker auth failed (401), refresh credentials")
}
return fmt.Errorf("unexpected response code: %d, body: %s", resp.StatusCode, string(contents)) Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: check Spinnaker reachability and auth
resp, err := http.Get(spinURL + "/health")
if err != nil || resp.StatusCode != http.StatusOK {
return fmt.Errorf("spinnaker unreachable or unhealthy")
} Try / catch
err := terminator.Execute(instance)
if err != nil {
if strings.Contains(err.Error(), "401") || strings.Contains(err.Error(), "403") {
// refresh credentials and retry once
} else if strings.Contains(err.Error(), "unexpected response code: 5") {
// retry with backoff
}
} Prevention
- Keep Spinnaker auth tokens fresh
- Validate instance IDs before killing
- Add retries for 5xx only
- Log the response body for diagnosis
When it happens
Trigger: Calling spinnaker.Terminator.Execute (kill) when the Spinnaker API returns 4xx (bad auth, bad payload) or 5xx (server error).
Common situations: Expired Spinnaker auth token, malformed instance ID, Spinnaker/Gate down or overloaded, wrong endpoint URL.
Related errors
- info.Error
- unexpected response code (%d) from %s
- no cloudProvider field in response body
- alternateAccountID called with forbidden arg: %s
- could not retrieve list of apps from spinnaker url %s: %v
AI-assisted analysis of Netflix/chaosmonkey@eaa28fb761 (2026-09-03).
Data as JSON: /api/errors/71017077f7e9a375.
Report an issue: GitHub.