grpc/grpc-go · error

request info not found from context

Error message

request info not found from context

What it means

Returned by dualPerRPCCreds.GetRequestMetadata when credentials.RequestInfoFromContext returns ok=false, meaning the RPC context carries no transport/peer auth info. dualPerRPCCreds needs the AuthType to decide between ALTS and TLS per-RPC credentials, so without request info it cannot route correctly. This typically indicates the credential was used outside a normal gRPC RPC pipeline.

Solutions

  1. Do not call dualPerRPCCreds.GetRequestMetadata directly; let gRPC invoke it during a real RPC.
  2. If testing, attach request info via credentials.NewContextWithRequestInfo or use the grpc test suite helpers.
  3. Upgrade google.golang.org/grpc so the transport reliably attaches request info to the context.

Example fix

// before
md, err := dualCreds.GetRequestMetadata(context.Background())
// after
// Let gRPC call GetRequestMetadata during a real RPC over a dialed connection.
Defensive patterns

Strategy: validation

Validate before calling

// dualPerRPCCreds is internal; do not call its GetRequestMetadata directly.
// If you must (tests), attach request info first:
func ctxWithRequestInfo(authInfo credentials.AuthInfo) context.Context {
    return credentials.NewContextWithRequestInfo(context.Background(), authInfo)
}

Try / catch

// This error indicates misuse; fix the caller rather than catching at runtime:
md, err := creds.GetRequestMetadata(ctx)
if err != nil && strings.Contains(err.Error(), "request info not found") {
    panic("GetRequestMetadata called outside gRPC RPC pipeline")
}

Prevention

When it happens

Trigger: Invoking dualPerRPCCreds.GetRequestMetadata directly (not via gRPC) with a plain context; a custom dialOption or interceptor that strips request info from the context before per-RPC credentials run; an older gRPC version that did not populate request info on the context.

Common situations: Unit tests that call GetRequestMetadata with context.Background(); middleware that re-creates the context losing the gRPC-added values; version skew between grpc core and the credentials/google subpackage.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/8c371426941121ce. Report an issue: GitHub.

Appendix: source

Thrown at credentials/google/google.go:167

	if mode == internal.CredsBundleModeFallback || mode == internal.CredsBundleModeBackendFromBalancer {
		newCreds.perRPCCreds = newCreds.opts.PerRPCCreds
	}

	return newCreds, nil
}

// dualPerRPCCreds implements credentials.PerRPCCredentials by embedding the
// fallback PerRPCCredentials and the ALTS one. It pickes one of them based on
// the channel type.
type dualPerRPCCreds struct {
	perRPCCreds     credentials.PerRPCCredentials
	altsPerRPCCreds credentials.PerRPCCredentials
}

func (d *dualPerRPCCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
	ri, ok := credentials.RequestInfoFromContext(ctx)
	if !ok {
		return nil, fmt.Errorf("request info not found from context")
	}
	if authType := ri.AuthInfo.AuthType(); authType == "alts" {
		return d.altsPerRPCCreds.GetRequestMetadata(ctx, uri...)
	}
	// This ensures backward compatibility even if authType is not "tls".
	return d.perRPCCreds.GetRequestMetadata(ctx, uri...)
}

func (d *dualPerRPCCreds) RequireTransportSecurity() bool {
	return d.altsPerRPCCreds.RequireTransportSecurity() || d.perRPCCreds.RequireTransportSecurity()
}

View on GitHub (pinned to 0c51461d27)