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 errView on GitHub (pinned to 482b49bf1a)
Solutions
- Verify the PeriodicLaunch has valid Namespace and ID before insertion.
- Inspect the wrapped error for the memdb schema complaint.
- Restart the server agent and let leadership re-election replay state from Raft.
- 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
- Ensure Namespace/ID are populated on PeriodicLaunch (especially after upgrades from pre-namespace versions)
- Accept duplicate launches on next tick as the built-in recovery path
- Keep all servers on the same Nomad version
- Restart the leader if insert errors repeat
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
- periodic launch lookup failed: %v
- launch not found
- error parsing: root should be an object
- cannot specify Accessor ID
- network already configured but not found in state
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/534c441df91248dc.
Report an issue: GitHub.