VictoriaMetrics/VictoriaMetrics · error

cannot unmarshal %q: %w

Error message

cannot unmarshal %q: %w

What it means

Request.Unmarshal decodes a DataDog /api/v1/series JSON body with encoding/json; if json.Unmarshal fails, the raw body and cause are wrapped in 'cannot unmarshal %q'. Typical causes are non-JSON bodies, malformed JSON, or wrong JSON shapes (e.g. points not [[ts,val]] arrays).

Source

Thrown at lib/protoparser/datadogv1/parser.go:33

func (req *Request) reset() {
	// recursively reset all the fields in req in order to avoid field value
	// reuse in json.Unmarshal() when the corresponding field is missing
	// in the unmarshaled JSON.
	// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3432
	series := req.Series
	for i := range series {
		series[i].reset()
	}
	req.Series = series[:0]
}

// Unmarshal unmarshals DataDog /api/v1/series request body from b to req.
//
// b shouldn't be modified when req is in use.
func (req *Request) Unmarshal(b []byte) error {
	req.reset()
	if err := json.Unmarshal(b, req); err != nil {
		return fmt.Errorf("cannot unmarshal %q: %w", b, err)
	}
	// Set missing timestamps to the current time.
	currentTimestamp := float64(fasttime.UnixTimestamp())
	series := req.Series
	for i := range series {
		points := series[i].Points
		for j := range points {
			if points[j][0] <= 0 {
				points[j][0] = currentTimestamp
			}
		}
	}
	return nil
}

// Series represents a series item from DataDog POST request to /api/v1/series
type Series struct {
	Metric string `json:"metric"`

View on GitHub (pinned to 5079fb58f1)

Solutions

  1. Validate the posted body with jq (jq . < body.json) to see JSON syntax errors
  2. Check the wrapped snippet %q shows what bytes actually arrived — often reveals wrong endpoint or mangling
  3. Fix the field types to match the /api/v1/series schema (points: [[number, number], ...])
  4. Send protobuf sketches to the sketches endpoint instead if the sender is a Datadog agent using v2

Example fix

// before
// body: {"series":[{"metric":"m","points":["1,2"]}]}
// error: cannot unmarshal "...": json: cannot unmarshal string into ...Points
// after
{"series":[{"metric":"m","points":[[1696000000,2]]}]}
Defensive patterns

Strategy: validation

Validate before calling

// Validate v1 series JSON shape before POSTing
func validV1(body []byte) bool {
    var req struct {
        Series []struct {
            Metric string     `json:"metric"`
            Points [][2]float64 `json:"points"`
        } `json:"series"`
    }
    return json.Unmarshal(body, &req) == nil && len(req.Series) > 0
}
if !validV1(body) { return errors.New("not a valid /api/v1/series JSON body") }

Type guard

func isDatadogV1JSON(body []byte) bool {
    var probe map[string]json.RawMessage
    if err := json.Unmarshal(body, &probe); err != nil { return false }
    _, ok := probe["series"]
    return ok
}

Try / catch

req := &datadogv1.Request{}
if err := req.Unmarshal(body); err != nil {
    log.Printf("v1 unmarshal failed for body %.200q: %v", body, err)
    http.Error(w, "bad request", http.StatusBadRequest)
}

Prevention

When it happens

Trigger: Client POSTs to the DataDog v1 import endpoint with a body that fails strict JSON decoding into the Request struct: invalid JSON syntax, unexpected types (string where number expected), or empty body.

Common situations: Configuring a DogStatsD or protobuf-sketch client against the v1 JSON endpoint, hand-written scripts posting malformed JSON, template/interpolation bugs producing invalid payloads, proxies mangling the body.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03). Data as JSON: /api/errors/037c4474ffe5f860. Report an issue: GitHub.