cloudflare/cloudflared · error

unable to unmarshal LogLevel string

Error message

unable to unmarshal LogLevel string

What it means

Thrown by LogLevel.UnmarshalJSON when the incoming JSON value for a log-level field is not a JSON string (e.g. number or object), so unmarshalling into a string fails. This is the malformed-payload case, distinct from the later 'unable to unmarshal LogLevel' case where the string is well-formed but not a recognized level.

Source

Thrown at management/events.go:178

	case Info:
		return "info"
	case Warn:
		return "warn"
	case Error:
		return "error"
	default:
		return ""
	}
}

func (l LogLevel) MarshalJSON() ([]byte, error) {
	return json.Marshal(l.String())
}

func (l *LogLevel) UnmarshalJSON(data []byte) error {
	var s string
	if err := json.Unmarshal(data, &s); err != nil {
		return errors.New("unable to unmarshal LogLevel string")
	}
	if level, ok := ParseLogLevel(s); ok {
		*l = level
		return nil
	}
	return fmt.Errorf("unable to unmarshal LogLevel")
}

const (
	// TimeKey aligns with the zerolog.TimeFieldName
	TimeKey = "time"
	// LevelKey aligns with the zerolog.LevelFieldName
	LevelKey = "level"
	// LevelKey aligns with the zerolog.MessageFieldName
	MessageKey = "message"
	// EventTypeKey is the custom JSON key of the LogEventType in ZeroLogEvent
	EventTypeKey = "event"
	// FieldsKey is a custom JSON key to match and store every other key for a zerolog event

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Send the log level as a JSON string, e.g. {"level": "debug"}
  2. Only use levels supported by ParseLogLevel (debug, info, warn, error, etc.)
  3. Inspect the raw payload for a wrongly-typed level field

Example fix

// before
{"level": 2}
// after
{"level": "debug"}
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := management.ParseLogLevel(s); !ok { /* unsupported level */ }

Type guard

func isKnownLogLevel(s string) bool { _, ok := management.ParseLogLevel(s); return ok }

Try / catch

var l management.LogLevel
if err := json.Unmarshal(data, &l); err != nil { log.Warn().Err(err).Msg("bad LogLevel payload") }

Prevention

When it happens

Trigger: json.Unmarshal inside LogLevel.UnmarshalJSON fails because the payload contains a non-string (number, bool, object) in a field expected to be a LogLevel string.

Common situations: A management-stream client sending a numeric log level or a malformed JSON message over the session.

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


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/18db0aaee7386038. Report an issue: GitHub.