hashicorp/nomad · error
failed to marshal json from Topic: %s, Type: %s, Err: %w
Error message
failed to marshal json from Topic: %s, Type: %s, Err: %w
What it means
For each non-error, non-heartbeat event, captureEventStream serializes the whole event struct with json.Marshal before writing it to eventstream.json. If marshaling fails, the event cannot be recorded and the failure is appended to the multierror with the event's Topic and Type. json.Marshal on well-formed event structs essentially only fails on unsupported channel/func/custom-marshaler values, so this usually indicates an unexpected event payload or a library-level serialization bug.
Source
Thrown at command/operator_debug.go:986
errCount++
c.verboseOutf("error from event stream: index; %d err: %v", event.Index, event.Err)
mErrs = multierror.Append(mErrs, fmt.Errorf("error at index: %d, Err: %w", event.Index, event.Err))
break
}
if event.IsHeartbeat() {
heartbeatCount++
continue
}
for _, e := range event.Events {
eventCount++
c.verboseOutf("Event: %4d, Index: %d, Topic: %-10s, Type: %s, FilterKeys: %s", eventCount, e.Index, e.Topic, e.Type, e.FilterKeys)
bytes, err := json.Marshal(e)
if err != nil {
errCount++
mErrs = multierror.Append(mErrs, fmt.Errorf("failed to marshal json from Topic: %s, Type: %s, Err: %w", e.Topic, e.Type, err))
}
n, err := fh.Write(bytes)
if err != nil {
errCount++
mErrs = multierror.Append(mErrs, fmt.Errorf("failed to write bytes to eventstream.json; bytes written: %d, Err: %w", n, err))
break
}
n, err = fh.WriteString("\n")
if err != nil {
errCount++
mErrs = multierror.Append(mErrs, fmt.Errorf("failed to write string to eventstream.json; chars written: %d, Err: %w", n, err))
}
}
case <-c.ctx.Done():
c.verboseOutf("Event stream captured %d events, %d frames, %d heartbeats, %d errors", eventCount, channelEventCount, heartbeatCount, errCount)
return mErrs.ErrorOrNil()
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Record the Topic and Type in the message and check whether that topic's events changed with a recent Consul version — upgrade/downgrade the CLI to match the agent
- Retry the capture; a single malformed frame loses only that event (errCount is tracked, loop continues)
- Update the consul CLI to a version whose event types marshal cleanly for your agent version
- If reproducible, report the unserializable Topic/Type upstream — this indicates a marshaling bug
Defensive patterns
Strategy: try-catch
Try / catch
bytes, err := json.Marshal(e)
if err != nil {
errs = multierror.Append(errs, fmt.Errorf("failed to marshal json from Topic: %s, Type: %s, Err: %w", e.Topic, e.Type, err))
continue // skip unserializable event, keep capture alive
} Prevention
- Keep the consul CLI version aligned with the agent version
- Note the failing Topic/Type and report persistent marshal failures upstream
- Retry the capture — a single bad frame only loses that event
When it happens
Trigger: json.Marshal(e) returns an error for a received event — e.g. an event type carrying a value its custom MarshalJSON rejects, or an internal field that cannot be represented in JSON.
Common situations: Capturing topics whose event payloads include exotic data; version mismatch between the CLI and the agent producing newer event fields with unsupported types; a bug in a custom MarshalJSON implementation.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- error marshaling json for stream: %w
- failed to decode and failed to read buffered data: %w
- failed to decode log endpoint response as JSON: %q
- error marshaling volume pramaters: %w
- could not serialize our own error: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0cb09509b819d8c2.
Report an issue: GitHub.