hashicorp/nomad · error

no identities to sign

Error message

no identities to sign

What it means

Signer.SignIdentities validates that the caller passed at least one WorkloadIdentityRequest; an empty request slice is a programming error, so it fails fast with this message instead of making a pointless RPC to the servers.

Source

Thrown at client/widmgr/signer.go:69

}

// SetNodeIdentityToken fulfills the NodeIdentityHandler interface, allowing
// the client to update the node identity token used for RPC calls when it is
// renewed.
func (s *Signer) SetNodeIdentityToken(token string) { s.nodeIdentityToken.Store(token) }

// SignIdentities wraps the Alloc.SignIdentities RPC and retrieves signed
// workload identities. The minIndex should be set to the lowest allocation
// CreateIndex to ensure that the server handling the request isn't so stale
// that it doesn't know the allocation exist (and therefore rejects the signing
// requests).
//
// Since a single rejection causes an error to be returned, SignIdentities
// should currently only be used when requesting signed identities for a single
// allocation.
func (s *Signer) SignIdentities(minIndex uint64, req []*structs.WorkloadIdentityRequest) ([]*structs.SignedWorkloadIdentity, error) {
	if len(req) == 0 {
		return nil, fmt.Errorf("no identities to sign")
	}

	// Default to using the node secret, but if the node identity token is set,
	// this will be used instead. This handles the case where the node is
	// upgraded before the Nomad servers and should be removed in Nomad 1.13.
	authToken := s.nodeSecret

	if id := s.nodeIdentityToken.Load(); id != nil {
		authToken = id.(string)
	}

	args := structs.AllocIdentitiesRequest{
		Identities: req,
		QueryOptions: structs.QueryOptions{
			Region: s.region,

			// Unlike other RPCs, this one doesn't care about "subsequent
			// modifications" after an index. We only want to ensure the state

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Ensure the caller only invokes SignIdentities when the allocation has at least one workload identity.
  2. Filter/log allocations lacking identities before requesting signing.
  3. Check upstream code that builds the []*structs.WorkloadIdentityRequest slice for an over-aggressive filter.

Example fix

// before
signed, err := signer.SignIdentities(0, reqs) // reqs may be empty
// after
if len(reqs) == 0 {
    return nil
}
signed, err := signer.SignIdentities(0, reqs)
Defensive patterns

Strategy: validation

Validate before calling

if len(reqs) == 0 {
    return nil // nothing to sign; skip the RPC entirely
}
signed, err := signer.SignIdentities(minIndex, reqs)

Prevention

When it happens

Trigger: Calling SignIdentities(minIndex, req) with req == nil or len(req) == 0 — e.g. an allocation with no workload identities, or a caller building the request slice from an empty filtered set.

Common situations: Tasks with no workload_identity blocks; a bug where identities were filtered out earlier; tests constructing a Signer and calling it with no requests.

Related errors


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