hashicorp/nomad · error

command did not include data

Error message

command did not include data

What it means

decode() parses a single raft log entry into a logMessage. When the entry type is raft.LogCommand, the payload must start with at least one byte (the message type) followed by the msgpack-encoded body. This error means the entry was marked as a command log but its Data field is empty, so there is no command type byte to inspect.

Source

Thrown at helper/raftutil/state.go:165

	IgnoreUnknownTypeFlag bool        `json:",omitempty"`
	Body                  interface{} `json:",omitempty"`
}

func decode(e *raft.Log) (*logMessage, error) {
	m := &logMessage{
		LogType: logTypes[e.Type],
		Term:    e.Term,
		Index:   e.Index,
	}

	if m.LogType == "" {
		m.LogType = fmt.Sprintf("%d", e.Type)
	}

	var data []byte
	if e.Type == raft.LogCommand {
		if len(e.Data) == 0 {
			return nil, fmt.Errorf("command did not include data")
		}

		msgType := structs.MessageType(e.Data[0])

		m.CommandType = commandName(msgType & ^structs.IgnoreUnknownTypeFlag)
		m.IgnoreUnknownTypeFlag = (msgType & structs.IgnoreUnknownTypeFlag) != 0

		data = e.Data[1:]
	} else {
		data = e.Data
	}

	if len(data) != 0 {
		decoder := codec.NewDecoder(bytes.NewReader(data), structs.MsgpackHandle)

		var v interface{}
		var err error
		if m.CommandType == commandName(structs.JobBatchDeregisterRequestType) {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Identify the affected log index from the accompanying 'failed to decode log entry at index %d' warning in LogEntries and treat that entry's data as unrecoverable.
  2. Restore the server's data directory from a verified backup or a healthy snapshot (nomad snapshot inspect/save) instead of trusting the corrupted raft log.
  3. Run a raft store integrity check (e.g. open raft.db with bbolt in read-only, or verify the WAL segment checksums) to confirm corruption extent.
  4. If the cluster is still quorate, remove the corrupted server from the cluster, wipe its data dir, and rejoin so raft is rebuilt from the leader.
  5. Redeploy the tooling against a snapshot archive rather than raw raft logs when only state inspection is needed.

Example fix

// before: tool aborts listing entries when it hits an empty LogCommand
entries, warnings, err := raftutil.LogEntries(dataDir)
// after: drain warnings and skip corrupt entries instead of failing the whole run
entries, warnings, err := raftutil.LogEntries(dataDir)
if err != nil { return err }
go func() {
    for w := range warnings {
        log.Printf("skipping bad raft entry: %v", w)
    }
}()
Defensive patterns

Strategy: validation

Validate before calling

// before trusting a LogCommand entry from LogEntries
entries, warnings, err := raftutil.LogEntries(dataDir)
if err != nil { return err }
for w := range warnings {
    if strings.Contains(w.Error(), "command did not include data") {
        log.Printf("corrupt empty command entry: %v", w)
    }
}

Try / catch

// Go: treat the warning channel as the error surface
for w := range warnings {
    if strings.Contains(w.Error(), "command did not include data") {
        // skip entry / mark store suspect
        continue
    }
}

Prevention

When it happens

Trigger: LogEntries is called on a raft store (raft.db or wal/) and one of the entries read back has Type == raft.LogCommand with len(e.Data) == 0 — i.e. a zero-length command log was persisted in the raft log store.

Common situations: Corrupted or truncated raft.db / WAL files after disk-full events, crashes mid-write, or improper copy/restore of the data directory; manually edited or partially recovered raft stores being inspected with the raftutil inspection tooling.

Related errors


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