slimtoolkit/slim · error

bad http status - %d

Error message

bad http status - %d

What it means

The EPSS API client's call() validates the HTTP response status; only success (and mapped NotFound/Forbidden sentinel errors) proceed. Any other non-success status — e.g. 500, 429, 401 — is converted to this error carrying the numeric status code. It indicates the remote EPSS service rejected or failed the request.

Source

Thrown at pkg/vulnerability/epss/api/api.go:542

			defer resp.Body.Close()
		}

		if err != nil {
			logger.WithError(err).Error("ref.client.Do")
			return resp, err
		}

		if resp.StatusCode != http.StatusOK {
			logger.WithField("status.code", resp.StatusCode).Error("ref.client.Do")

			if resp.StatusCode == http.StatusNotFound {
				return resp, epss.ErrNotFound
			}
			if resp.StatusCode == http.StatusForbidden {
				return resp, epss.ErrNotAuthorized
			}

			return resp, fmt.Errorf("bad http status - %d", resp.StatusCode)
		}

		if output != nil {
			var b bytes.Buffer
			b.ReadFrom(resp.Body)

			if output.decoded != nil && outFormat == epss.OutJSON {
				//non-json responses are returned as raw strings
				decoder := json.NewDecoder(bytes.NewReader(b.Bytes()))
				err = decoder.Decode(output.decoded)
				if err != nil {
					logger.WithFields(log.Fields{
						"error":          err,
						"output.decoded": output.decoded,
					}).Error("decoder.Decode")
					return resp, err
				}
			}

View on GitHub (pinned to 81940d17fa)

Solutions

  1. Log/inspect resp.StatusCode and retry with exponential backoff for transient 5xx/429 statuses.
  2. Check API credentials and quota if the status is 401/403.
  3. Check the EPSS service status page/endpoint availability before assuming client error.
  4. Verify network/proxy configuration if the status indicates an intermediary error.

Example fix

// before
resp, err := client.GenericLookupCall(cve)
if err != nil { return err }
// after
resp, err := client.GenericLookupCall(cve)
if err != nil {
    var statusErr *fmt.Errorf // unwrap to inspect status
    if strings.Contains(err.Error(), "bad http status - 429") {
        time.Sleep(backoff); return retry(cve)
    }
    return err
}
Defensive patterns

Strategy: retry

Try / catch

resp, err := client.GenericLookupCall(cve)
if err != nil {
    if errors.Is(err, epss.ErrNotFound) { return nil, nil }
    if errors.Is(err, epss.ErrNotAuthorized) { return nil, fmt.Errorf("check EPSS credentials") }
    if strings.Contains(err.Error(), "bad http status - 429") ||
       strings.Contains(err.Error(), "bad http status - 5") {
        return backoffRetry(cve)
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling GenericListCall or GenericLookupCall when the EPSS HTTP endpoint returns an unexpected status: server errors (5xx), rate limiting (429), or authentication failures (401) other than the 403 sentinel.

Common situations: EPSS service outage, aggressive polling hitting rate limits, expired or missing API credentials in the environment, or a proxy returning an error page.

Related errors


AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31). Data as JSON: /api/errors/7dd071b086a0523b. Report an issue: GitHub.