ent/ent · error

gremlin/http: decoding response: %w

Error message

gremlin/http: decoding response: %w

What it means

This error is returned by the Gremlin HTTP transport's RoundTrip when the response body cannot be decoded as GraphSON into the library's Response struct. It wraps the underlying graphson decoder error, which typically indicates the server sent HTML (an error page), JSON in an unexpected shape, an unsupported GraphSON version, or truncated output (also guarded by MaxResponseSize).

Source

Thrown at dialect/gremlin/http.go:82

		rsp, err := t.client.Do(req.WithContext(ctx))
		if err != nil {
			return nil, fmt.Errorf("gremlin/http: posting http request: %w", err)
		}
		defer rsp.Body.Close()

		if rsp.StatusCode < http.StatusOK || rsp.StatusCode > http.StatusPartialContent {
			body, _ := io.ReadAll(rsp.Body)
			return nil, fmt.Errorf("gremlin/http: status=%q, body=%q", rsp.Status, body)
		}
		if rsp.ContentLength > MaxResponseSize {
			return nil, errors.New("gremlin/http: context length exceeds limit")
		}
		br = rsp.Body
	}

	var rsp Response
	if err := graphson.NewDecoder(io.LimitReader(br, MaxResponseSize)).Decode(&rsp); err != nil {
		return nil, fmt.Errorf("gremlin/http: decoding response: %w", err)
	}
	return &rsp, nil
}

View on GitHub (pinned to 69d5d4deb1)

Solutions

  1. Inspect the raw response body (e.g. with a debug http.Client RoundTripper) to see what the server actually returned.
  2. Check the Gremlin server serializer configuration — set GraphSONv3 (org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3) to match what the client expects.
  3. If the body is HTML, look for a proxy/load balancer between the client and Gremlin and bypass or fix it.
  4. If the traversal returns very large result sets, reduce result size (limit(), pagination) so the response fits within MaxResponseSize.

Example fix

// before: server uses GraphSONv1, client fails to decode
// gremlin-server.yaml: GraphSONMessageSerializerV1d
// after: configure server serializer to GraphSON v3
// gremlin-server.yaml:
//   serializers:
//     - className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3
Defensive patterns

Strategy: validation

Validate before calling

// verify the server speaks GraphSON the client understands before dialing
resp, err := http.Post(uri, "application/json", strings.NewReader(`{"requestId":"test","opName":""}`))
if err == nil {
    b, _ := io.ReadAll(io.LimitReader(resp.Body, 1024))
    resp.Body.Close()
    if !json.Valid(b) && strings.Contains(string(b), "<html") {
        return errors.New("gremlin endpoint returned HTML, not GraphSON — check proxy/serializer")
    }
}

Try / catch

r, err := client.Exec(ctx, g.V())
if err != nil {
    if strings.Contains(err.Error(), "decoding response") {
        // capture body via a debug RoundTripper and inspect raw payload
        return fmt.Errorf("non-GraphSON response, check proxy/serializer: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Decoding the response body via graphson.NewDecoder(io.LimitReader(br, MaxResponseSize)).Decode(&rsp) fails: body is HTML/plain text (proxy or error page), GraphSON version mismatch (GraphSONv1 vs v3), malformed JSON from a proxy intercepting traffic, or body exceeds MaxResponseSize and is truncated.

Common situations: Reverse proxy or load balancer returning an HTML 502 page; Gremlin server configured with a serializer (GraphSONv1) unsupported by the client's decoder; middleware (WAF) altering the response; response larger than MaxResponseSize cut off mid-stream by the LimitReader.

Related errors


AI-assisted analysis of ent/ent@69d5d4deb1 (2026-09-03). Data as JSON: /api/errors/c268702dc036d91e. Report an issue: GitHub.