cilium/cilium · error

Failed to Unquote string: %s %s

Error message

Failed to Unquote string: %s
%s

What it means

expandNestedJSON in cilium-dbg scans command output for strings containing escaped nested JSON and tries to pretty-print it. It extracts the matched quoted region and calls strconv.Unquote on it; if that region is not a valid Go-quoted string literal, Unquote fails and this error is returned. It indicates the regexp matched something that looks like embedded JSON but is not actually a syntactically valid quoted string.

Source

Thrown at cilium-dbg/cmd/helpers.go:121

		}

		// Determine the current indentation
		for i := range loc[0] - 1 {
			idx := loc[0] - i - 1
			if resBytes[idx] != ' ' {
				break
			}
			indent = fmt.Sprintf("\t%s\t", indent)
		}

		stringStart := loc[0]
		stringEnd := loc[1]

		// Unquote the string with the nested json.
		quotedBytes := resBytes[stringStart:stringEnd]
		unquoted, err := strconv.Unquote(string(quotedBytes))
		if err != nil {
			return bytes.Buffer{}, fmt.Errorf("Failed to Unquote string: %s\n%s", err.Error(), string(quotedBytes))
		}

		// Find the JSON within the unquoted string.
		nestedStart := 0
		nestedEnd := 0
		// Find the left-most match
		if loc = reJSON.FindStringIndex(unquoted); loc != nil {
			nestedStart = loc[0]
			nestedEnd = loc[1]
		}

		// Decode the nested JSON
		decoded := ""
		if nestedEnd != 0 {
			m := make(map[string]any)
			nested := bytes.NewBufferString(unquoted[nestedStart:nestedEnd])
			if err := json.NewDecoder(nested).Decode(&m); err != nil {
				return bytes.Buffer{}, fmt.Errorf("Failed to decode nested JSON: %s (\n%s\n)", err.Error(), unquoted[nestedStart:nestedEnd])

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Inspect the quoted fragment printed in the error and fix the source string's quoting/escapes at the producing side.
  2. Validate the string with strconv.CanBackquote or strconv.Unquote in a test harness before relying on nested-JSON expansion.
  3. Disable nested JSON expansion (dump output without pretty-print flags / use --output json) so expandNestedJSON is not invoked on the region.
  4. If output is truncated, increase terminal width/capture full output to a file before running the command.

Example fix

// before: string fragment with invalid escape breaks Unquote
bad := "[{\"labels\":\"k8s:io.\x01bad\"}]"
// after: ensure proper escaping at the producer
quoted := strconv.Quote(goodJSONString) // valid Go quoted literal
unquoted, err := strconv.Unquote(quoted)
if err != nil { return fmt.Errorf("invalid quoted JSON: %w", err) }
Defensive patterns

Strategy: validation

Validate before calling

func isGoQuoted(s string) bool { _, err := strconv.Unquote(s); return err == nil }
if !isGoQuoted(fragment) { /* skip expansion or log and fall back to raw output */ }

Type guard

func validQuotedJSON(b []byte) bool { u, err := strconv.Unquote(string(b)); return err == nil && json.Valid([]byte(u)) }

Try / catch

out, err := expandNestedJSON(buf)
if err != nil {
    log.Printf("nested JSON expansion skipped: %v", err)
    out = buf // fall back to raw output
}

Prevention

When it happens

Trigger: Calling a cilium-dbg command whose output goes through expandNestedJSON (e.g. `cilium bpf policy get` / endpoint list output) where the regex `"[^"\\{]*{.*[^\\]"` matches a malformed quoted fragment: unbalanced quotes, invalid escape sequences (e.g. \x sequences Go's Unquote rejects), or a match spanning truncating output.

Common situations: Piping output of cilium-dbg commands whose nested JSON label/annotation data contains unusual escapes; output truncated by terminal width or log rotation mid-string; regex false positives on strings containing braces that are not real JSON strings.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/225f19d550c271e9. Report an issue: GitHub.