grafana/k6 · error

failed to create request metadata request: %w

Error message

failed to create request metadata request: %w

What it means

Returned by newBatchCreateRequestMetadatasRequest in internal/cloudapi/insights/mappers.go:18 when any single entry of a RequestMetadatas batch fails to map into the protobuf ingester type. It is a pure wrapper: the %w chain always ends in the only real error source in this file, setProtocolLabels' 'unknown protocol labels type' (mappers.go:63), because newCreateRequestMetadataRequest itself cannot otherwise fail. The whole batch is abandoned on the first bad entry.

Source

Thrown at internal/cloudapi/insights/mappers.go:18

package insights

import (
	"errors"
	"fmt"

	"go.k6.io/k6/v2/internal/cloudapi/insights/proto/v1/ingester"
	"go.k6.io/k6/v2/internal/cloudapi/insights/proto/v1/k6"
)

func newBatchCreateRequestMetadatasRequest(
	requestMetadatas RequestMetadatas,
) (*ingester.BatchCreateRequestMetadatasRequest, error) {
	reqs := make([]*ingester.CreateRequestMetadataRequest, 0, len(requestMetadatas))
	for _, rm := range requestMetadatas {
		req, err := newCreateRequestMetadataRequest(rm)
		if err != nil {
			return nil, fmt.Errorf("failed to create request metadata request: %w", err)
		}

		reqs = append(reqs, req)
	}

	return &ingester.BatchCreateRequestMetadatasRequest{
		Requests: reqs,
	}, nil
}

func newCreateRequestMetadataRequest(requestMetadata RequestMetadata) (*ingester.CreateRequestMetadataRequest, error) {
	rm := &k6.RequestMetadata{
		TraceID:           requestMetadata.TraceID,
		StartTimeUnixNano: requestMetadata.Start.UnixNano(),
		EndTimeUnixNano:   requestMetadata.End.UnixNano(),
		TestRunLabels: &k6.TestRunLabels{
			ID:       requestMetadata.TestRunLabels.ID,
			Scenario: requestMetadata.TestRunLabels.Scenario,

View on GitHub (pinned to 01ffac6f24)

Solutions

  1. Unwrap the error chain and confirm the root cause is 'unknown protocol labels type'; identify which batch entry carries the unsupported labels type.
  2. If your batch can contain non-HTTP entries, filter them out (or skip nil ProtocolLabels) before calling the batch mapper — only ProtocolHTTPLabels is supported today.
  3. If you are adding a new protocol, extend the type switch in setProtocolLabels (mappers.go:53) with a case mapping your labels to the corresponding k6.RequestMetadata_* protobuf oneof member, and regenerate proto types if needed.
  4. Re-run and verify the batch maps fully by checking that the error no longer surfaces in the insights ingest path.

Example fix

// before (mappers.go setProtocolLabels): only HTTP is mapped
	switch l := labels.(type) {
	case ProtocolHTTPLabels:
		rm.ProtocolLabels = &k6.RequestMetadata_HTTPLabels{...}
	default:
		return errors.New("unknown protocol labels type")
	}

// after: also tolerate nil / map a new protocol
	switch l := labels.(type) {
	case ProtocolHTTPLabels:
		rm.ProtocolLabels = &k6.RequestMetadata_HTTPLabels{...}
	case ProtocolGRPCLabels: // new protocol support
		rm.ProtocolLabels = &k6.RequestMetadata_GRPCLabels{...}
	case nil:
		return nil // no protocol-specific labels
	default:
		return errors.New("unknown protocol labels type")
	}
Defensive patterns

Strategy: validation

Validate before calling

// Filter a batch to entries the insights mapper can handle before calling it.
func supportedForInsights(rms insights.RequestMetadatas) insights.RequestMetadatas {
	out := make(insights.RequestMetadatas, 0, len(rms))
	for _, rm := range rms {
		if rm.ProtocolLabels == nil {
			continue
		}
		if _, ok := rm.ProtocolLabels.(insights.ProtocolHTTPLabels); !ok {
			continue
		}
		out = append(out, rm)
	}
	return out
}

Type guard

func isSupportedProtocolLabels(l insights.ProtocolLabels) bool {
	_, ok := l.(insights.ProtocolHTTPLabels)
	return ok
}

Try / catch

if _, err := insights.BuildBatchRequest(rms); err != nil {
	var protoErr *insights.UnsupportedProtocolError // if introduced; else match on message
	if errors.As(err, &protoErr) || strings.Contains(err.Error(), "unknown protocol labels type") {
		// drop unsupported entries and rebuild, or skip insights for this batch
	}
}

Prevention

When it happens

Trigger: Calling newBatchCreateRequestMetadatasRequest (or the insights push path above it) with a batch in which at least one RequestMetadata has ProtocolLabels that is nil or any type other than ProtocolHTTPLabels — the switch in setProtocolLabels (mappers.go:51-64) has only a ProtocolHTTPLabels case plus a default that errors, per the 'TODO(other-proto-support)' comment.

Common situations: Extending k6 insights to a new protocol (gRPC, WebSocket) and passing its label struct before adding a case in setProtocolLabels; constructing RequestMetadata programmatically (xk6 extension or tests) and leaving ProtocolLabels unset; a nil ProtocolLabels sneaking in for non-HTTP requests during a mixed-protocol test run.

Related errors


AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18). Data as JSON: /api/errors/0e0ca1b2b53d3331. Report an issue: GitHub.