hashicorp/nomad · error

launch delete failed: %v

Error message

launch delete failed: %v

What it means

Returned by StateStore.DeletePeriodicLaunchTxn when txn.Delete on the 'periodic_launch' table fails after the record was found. The launch exists but memdb refuses the delete, aborting the transaction (it will not be committed by the wrapper).

Source

Thrown at nomad/state/state_store.go:3396

	}
	return err
}

// DeletePeriodicLaunchTxn is used to delete the periodic launch, like DeletePeriodicLaunch
// but in a transaction.  Useful for when making multiple modifications atomically
func (s *StateStore) DeletePeriodicLaunchTxn(index uint64, namespace, jobID string, txn Txn) error {
	// Lookup the launch
	existing, err := txn.First("periodic_launch", "id", namespace, jobID)
	if err != nil {
		return fmt.Errorf("launch lookup failed: %v", err)
	}
	if existing == nil {
		return fmt.Errorf("launch not found")
	}

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

	return nil
}

// PeriodicLaunchByID is used to lookup a periodic launch by the periodic job
// ID.
func (s *StateStore) PeriodicLaunchByID(ws memdb.WatchSet, namespace, id string) (*structs.PeriodicLaunch, error) {
	txn := s.db.ReadTxn()

	watchCh, existing, err := txn.FirstWatch("periodic_launch", "id", namespace, id)
	if err != nil {
		return nil, fmt.Errorf("periodic launch lookup failed: %v", err)
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check the wrapped inner memdb error in the message for the exact cause
  2. Restart nomad servers so in-memory state is rebuilt from raft snapshots
  3. Ensure all writers use the canonical state store apply path (no custom txns against s.db)
  4. If it follows an upgrade, verify all servers run the same nomad version
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm the launch exists and is the expected type first
raw, err := txn.First("periodic_launch", "id", ns, jobID)
if err != nil { return err }
if _, ok := raw.(*structs.PeriodicLaunch); !ok { return fmt.Errorf("unexpected row type") }

Type guard

if l, ok := raw.(*structs.PeriodicLaunch); ok { /* use l */ }

Try / catch

if err := state.DeletePeriodicLaunch(idx, ns, jobID); err != nil {
	if strings.Contains(err.Error(), "launch delete failed") {
		// log wrapped memdb cause; plan a server restart if persistent
	}
	return err
}

Prevention

When it happens

Trigger: Calling DeletePeriodicLaunch/DeletePeriodicLaunchTxn when the memdb Delete of the existing PeriodicLaunch object errors — e.g. object/table mismatch inside memdb or an invalid txn state.

Common situations: Mixed-version agents writing incompatible objects into the state store; in-memory DB corruption; bespoke code passing objects of the wrong type into a shared txn.

Related errors


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