hashicorp/nomad · error

no signed workload identity available

Error message

no signed workload identity available

What it means

Nomad's Vault hook fails with 'no signed workload identity available' when deriving a Vault login JWT for workload identity-based auth (Vault 1.16+/JWT auth) and the allocrunner returned a nil signed identity without an error. Unlike the empty-string retrieval error above, this indicates the identity store produced nothing, and it is returned as a non-recoverable error, so the task will not retry automatically.

Source

Thrown at client/allocrunner/taskrunner/vault_hook.go:383

}

// deriveVaultTokenJWT returns a Vault ACL token using JWT auth login.
func (h *vaultHook) deriveVaultTokenJWT(ctx context.Context) (string, int, error) {
	// Retrieve signed identity.
	signed, err := h.widmgr.Get(structs.WIHandle{
		IdentityName:       h.widName,
		WorkloadIdentifier: h.task.Name,
		WorkloadType:       structs.WorkloadTypeTask,
	})
	if err != nil {
		return "", 0, structs.NewRecoverableError(
			fmt.Errorf("failed to retrieve signed workload identity: %w", err),
			true,
		)
	}
	if signed == nil {
		return "", 0, structs.NewRecoverableError(
			errors.New("no signed workload identity available"),
			false,
		)
	}

	role := h.vaultConfig.Role
	if h.vaultBlock.Role != "" {
		role = h.vaultBlock.Role
	}

	// Derive Vault token with signed identity.
	token, renewable, leaseDuration, err := h.client.DeriveTokenWithJWT(ctx, vaultclient.JWTLoginRequest{
		JWT:       signed.JWT,
		Role:      role,
		Namespace: h.vaultBlock.Namespace,
	})
	if err != nil {
		return "", 0, structs.WrapRecoverable(
			fmt.Sprintf("failed to derive Vault token for identity %s: %v", h.widName, err),

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Ensure the Nomad client version supports Vault workload identities and the client's vault config has the correct default cluster/jwt auth setup
  2. Check that the job's vault block and the Vault role (bound_audiences / Nomad audience) line up so a signed identity is minted for the alloc
  3. Resubmit the job / restart the allocation so identities are (re)issued, then check alloc events for recovery
  4. Fall back to legacy vault token derivation (vault token policy) if your Vault/Nomad versions don't support WI auth
  5. Inspect agent logs around deriveVaultToken for the earlier 'failed to retrieve signed workload identity' error to find the root cause

Example fix

// before (job)
vault {
  role = "web" // no matching signed identity minted
}
// after: use policies or ensure role/audience configured
vault {
  policies = ["web-read"]
  // or ensure nomad client vault config and Vault JWT auth role 'nomad-workloads' includes audience for this cluster
}
Defensive patterns

Strategy: try-catch

Try / catch

jwt, ttl, err := h.deriveVaultTokenJWT(ctx, nil)
if err != nil {
    var recov *structs.RecoverableError
    if errors.As(err, &recov) && recov.IsRecoverable() {
        return retryWithBackoff(err) // only recoverable errors retry
    }
    if strings.Contains(err.Error(), "no signed workload identity available") {
        return fmt.Errorf("workload identity not issued; check nomad/vault WI auth config: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: deriveVaultTokenJWT calls the workload identity signer during token derivation; the signer returns success but a nil identity — e.g. the task has no matching signed identity minted (missing/incorrect vault block role wiring, identity not yet issued for the alloc) despite the vault block requesting WI auth.

Common situations: Nomad client older than the workload-identity feature or Vault cluster not configured for Nomad JWT auth; the vault block lacks a matching workload identity audience/role on the client; race where the task starts before its identity is signed; job specifies vault role but the client's vault config doesn't enable WI-based tokens.

Related errors


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