owasp-amass/amass · error
failed to unmarchal the JSON
Error message
failed to unmarchal the JSON
What it means
JSONLogToRecord converts a JSON-formatted log line emitted by the engine session into a slog.Record. If json.Unmarshal fails on the input string, the function cannot proceed and returns this generic error (note the typo 'unmarchal' in the message). It throws because a non-JSON or truncated line cannot be mapped to a structured record.
Source
Thrown at internal/afmt/slog.go:20
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
// SPDX-License-Identifier: Apache-2.0
package afmt
import (
"encoding/json"
"errors"
"fmt"
"log/slog"
"strconv"
"time"
)
func JSONLogToRecord(logstr string) (slog.Record, error) {
j := make(map[string]any)
// unmarshal the log message sent from the engine session
if err := json.Unmarshal([]byte(logstr), &j); err != nil {
return slog.Record{}, errors.New("failed to unmarchal the JSON")
}
ltime := time.Now()
if timeVal, found := j[slog.TimeKey]; found {
if timestr, valid := timeVal.(string); valid {
if t, err := time.Parse("2006-01-02T15:04:05.000000000Z", timestr); err == nil {
ltime = t
}
}
}
delete(j, slog.TimeKey)
var level slog.Level
// extract the log level for the new record
if val, found := j[slog.LevelKey]; !found {
return slog.Record{}, errors.New("failed to find the level key")
} else if str, ok := val.(string); !ok {
return slog.Record{}, errors.New("failed to cast the level value")View on GitHub (pinned to 79299dce87)
Solutions
- Ensure the engine session writes one complete JSON object per line (JSON Lines format)
- Validate the input with json.Valid([]byte(logstr)) before calling JSONLogToRecord and log raw lines that fail
- Check for truncation — read full lines with a scanner and proper buffer size
- Confirm the engine and the log consumer use the same serialization options (no HTML escaping or custom field differences that break parsing)
Example fix
// before
if err := json.Unmarshal([]byte(logstr), &j); err != nil {
return slog.Record{}, errors.New("failed to unmarchal the JSON")
}
// after
if !json.Valid([]byte(logstr)) {
return slog.Record{}, fmt.Errorf("failed to unmarshal the JSON: %q", logstr)
}
if err := json.Unmarshal([]byte(logstr), &j); err != nil {
return slog.Record{}, fmt.Errorf("failed to unmarshal the JSON: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
if !json.Valid([]byte(logstr)) {
// route to raw-log sink instead of JSONLogToRecord
return errors.New("not a JSON log line")
} Try / catch
rec, err := afmt.JSONLogToRecord(line)
if err != nil {
if strings.Contains(err.Error(), "unmarchal the JSON") {
rawLog.Printf("non-JSON log line dropped: %q", line)
return nil
}
return err
} Prevention
- Write engine logs strictly in JSON Lines format (one object per line)
- Use a bufio.Scanner with a large buffer to avoid truncated lines
- Never interleave plain-text output with the JSON log stream
- Add a unit test round-tripping representative engine log lines through JSONLogToRecord
When it happens
Trigger: WriteLogMessage receives a logstr that is not valid JSON: empty string, plain-text log line, partially written/truncated line from a broken pipe, or a line with a JSON-unrepresentable payload.
Common situations: Mixing human-readable and JSON log formats in the same stream; reading a line before the writer finished flushing; engine emitting a stack trace or multi-line message; encoding bugs upstream.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- failed to find the level key
- failed to cast the level value
- failed to unmarshal the level text
- received insufficient data from the WHOIS server
- logger handler is not enabled
AI-assisted analysis of owasp-amass/amass@79299dce87 (2026-09-06).
Data as JSON: /api/errors/ae6d28e4a1cca3a0.
Report an issue: GitHub.