hashicorp/nomad · warning

error reading attribute %s. digitalocean metadata api return

Error message

error reading attribute %s. digitalocean metadata api returned an error: resp_code: %d, resp_body: %s

What it means

The DigitalOcean fingerprinter's Get method calls the DO metadata API (169.254.169.254/metadata/v1/<attribute>). When the HTTP response status is anything other than 200 OK, it logs and returns this error including the status code and response body.

Source

Thrown at client/fingerprint/env_digitalocean.go:108

		},
	}

	res, err := f.client.Do(req)
	if err != nil {
		f.logger.Debug("failed to request metadata", "attribute", attribute, "error", err)
		return "", err
	}

	body, err := io.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		f.logger.Error("failed to read metadata", "attribute", attribute, "error", err, "resp_code", res.StatusCode)
		return "", err
	}

	if res.StatusCode != http.StatusOK {
		f.logger.Debug("could not read value for attribute", "attribute", attribute, "resp_code", res.StatusCode)
		return "", fmt.Errorf("error reading attribute %s. digitalocean metadata api returned an error: resp_code: %d, resp_body: %s", attribute, res.StatusCode, body)
	}

	return string(body), nil
}

func (f *EnvDigitalOceanFingerprint) Fingerprint(request *FingerprintRequest, response *FingerprintResponse) error {
	cfg := request.Config

	// Check if we should tighten the timeout
	if cfg.ReadBoolDefault(TightenNetworkTimeoutsConfig, false) {
		f.client.Timeout = 1 * time.Millisecond
	}

	if err := f.digitalOceanProbe(); err != nil {
		return wrapProbeError(err)
	}

	// Keys and whether they should be namespaced as unique. Any key whose value

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the droplet actually supports the requested metadata attribute (curl http://169.254.169.254/metadata/v1/hostname)
  2. Check the resp_code in the message: 404 means attribute unsupported, 5xx means DO service issue
  3. Confirm the DO fingerprint is enabled only on DigitalOcean hosts
  4. Check network rules allowing link-local metadata traffic

Example fix

// before: probing unsupported attribute
doGet(ctx, "tags") // 404 on old droplets
// after: check availability first
if body, err := doGet(ctx, "tags"); err == nil { ... } // or guard feature-detection
Defensive patterns

Strategy: try-catch

Validate before calling

resp, err := http.Get("http://169.254.169.254/metadata/v1/hostname")
if err != nil || resp.StatusCode != http.StatusOK { /* not a DO droplet or API issue — skip fingerprint */ }

Type guard

func doMetadataHealthy(ctx context.Context) bool { req, _ := http.NewRequestWithContext(ctx, "GET", "http://169.254.169.254/metadata/v1/hostname", nil); resp, err := http.DefaultClient.Do(req); if err != nil { return false }; defer resp.Body.Close(); return resp.StatusCode == http.StatusOK }

Try / catch

val, err := f.Get(ctx, "hostname")
if err != nil {
    var httpErr interface{ HTTPStatusCode() int }
    if errors.As(err, &httpErr) && httpErr.HTTPStatusCode() == 404 { /* attribute unsupported */ }
    return err
}

Prevention

When it happens

Trigger: Metadata endpoint returns non-200 for the requested attribute — unknown attribute path, service unavailable, or an intermediate proxy returning an error page.

Common situations: Running the fingerprinter outside DigitalOcean (connection refused handled earlier) or a DO API hiccup; requesting an attribute not present on older droplets; firewall blocking the metadata service.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/f266c4b0de929675. Report an issue: GitHub.