hashicorp/nomad · error

missing target RPC

Error message

missing target RPC

What it means

The Agent.Profile RPC targets a specific server rather than the leader, so the endpoint manually performs region forwarding using args.RequestRegion(). If the request does not carry a target region, the endpoint cannot decide where to route the profiling request and returns this error. It is a request-validation failure, not a runtime condition.

Solutions

  1. Set the region on the request (via the Nomad API client's SetRegion or by populating RequestRegion) before calling Agent.Profile.
  2. Use the official Nomad HTTP API (`/v1/agent/profiling/...`) instead of raw RPCs so region handling is automatic.

Example fix

// before
args := &agent.ProfileRequest{} // region empty
// after
args := &agent.ProfileRequest{}
args.SetRegion("us-east-1") // or use QueryOptions.Region via the HTTP API
Defensive patterns

Strategy: validation

Validate before calling

if args.RequestRegion() == "" {
    return fmt.Errorf("Agent.Profile requires a target region")
}

Prevention

When it happens

Trigger: Sending an Agent.Profile RPC whose request struct has an empty RequestRegion — e.g. a raw RPC call or custom client that never populated the region field, bypassing the standard Nomad API client that sets it automatically.

Common situations: Hand-rolled RPC tooling or Go clients using the low-level api package incorrectly; requests constructed by copying another RPC without SetRegion; proxy implementations stripping the region field.

Related errors


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

Appendix: source

Thrown at nomad/client_agent_endpoint.go:63

	// Check ACL for agent write
	aclObj, err := a.srv.ResolveACL(args)
	if err != nil {
		return err
	} else if !aclObj.AllowAgentWrite() {
		// we're not checking AllowAgentDebug here because the target might not
		// be this server, and the server doesn't know if enable_debug has been
		// set on the target
		return structs.ErrPermissionDenied
	}

	// Forward to different region if necessary
	// this would typically be done in a.srv.forward() but since
	// we are targeting a specific server, not just the leader
	// we must manually handle region forwarding here.
	region := args.RequestRegion()
	if region == "" {
		return fmt.Errorf("missing target RPC")
	}

	if region != a.srv.Region() {
		// Mark that we are forwarding
		args.SetForwarded()
		return a.srv.forwardRegion(region, "Agent.Profile", args, reply)
	}

	// Targeting a node, forward request to node
	if args.NodeID != "" {
		return a.forwardProfileClient(args, reply)
	}

	// Handle serverID not equal to ours
	if args.ServerID != "" {
		serverToFwd, err := a.forwardFor(args.ServerID, region)
		if err != nil {
			return err

View on GitHub (pinned to 482b49bf1a)