hashicorp/nomad · error

launch insert failed: %v

Error message

launch insert failed: %v

What it means

UpsertPeriodicLaunch writes the PeriodicLaunch record via txn.Insert("periodic_launch", launch); failure returns this error and aborts the transaction, so the periodic job's launch bookkeeping is not persisted and the job may be launched again on the next tick. Insert failures usually mean the object violates the table's index schema or memdb is corrupt.

Source

Thrown at nomad/state/state_store.go:3361

	// Check if the job already exists
	existing, err := txn.First("periodic_launch", "id", launch.Namespace, launch.ID)
	if err != nil {
		return fmt.Errorf("periodic launch lookup failed: %v", err)
	}

	// Setup the indexes correctly
	if existing != nil {
		launch.CreateIndex = existing.(*structs.PeriodicLaunch).CreateIndex
		launch.ModifyIndex = index
	} else {
		launch.CreateIndex = index
		launch.ModifyIndex = index
	}

	// Insert the job
	if err := txn.Insert("periodic_launch", launch); err != nil {
		return fmt.Errorf("launch insert failed: %v", err)
	}
	if err := txn.Insert("index", &IndexEntry{"periodic_launch", index}); err != nil {
		return fmt.Errorf("index update failed: %v", err)
	}

	return txn.Commit()
}

// DeletePeriodicLaunch is used to delete the periodic launch
func (s *StateStore) DeletePeriodicLaunch(index uint64, namespace, jobID string) error {
	txn := s.db.WriteTxn(index)
	defer txn.Abort()

	err := s.DeletePeriodicLaunchTxn(index, namespace, jobID, txn)
	if err == nil {
		return txn.Commit()
	}
	return err

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the PeriodicLaunch has valid Namespace and ID before insertion.
  2. Inspect the wrapped error for the memdb schema complaint.
  3. Restart the server agent and let leadership re-election replay state from Raft.
  4. Upgrade/downgrade so all servers run the same Nomad version.
Defensive patterns

Strategy: validation

Validate before calling

func validLaunch(l *structs.PeriodicLaunch) error {
    if l == nil || l.ID == "" || l.Namespace == "" {
        return errors.New("periodic launch requires non-empty ID and Namespace")
    }
    return nil
}
if err := validLaunch(launch); err != nil { return err }
return store.UpsertPeriodicLaunch(index, launch)

Type guard

func validLaunch(l *structs.PeriodicLaunch) bool {
    return l != nil && l.ID != "" && l.Namespace != ""
}

Try / catch

if err := store.UpsertPeriodicLaunch(index, launch); err != nil {
    if strings.Contains(err.Error(), "launch insert failed") {
        // txn aborted; the job will be launched again on the next tick
        log.Warn("periodic launch not persisted; will retry next tick", "err", err)
        return err
    }
    return err
}

Prevention

When it happens

Trigger: Periodic job evaluation/launch where txn.Insert of the PeriodicLaunch struct fails — e.g. missing Namespace or ID fields required by the "id" index.

Common situations: Launch records missing namespace after upgrade from pre-0.8-style state, corrupted job objects, or version-skewed servers.

Related errors


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