cilium/cilium · error

failed to parse text: %w

Error message

failed to parse text: %w

What it means

Returned by nodeStatusFromOutput when the exec output is not valid JSON, so the CLI falls back to nodeStatusFromText (line-oriented `key: value` parsing), and that text parser also fails. The library tries JSON first, then a plain-text fallback modeled on `cilium encrypt status` human output.

Source

Thrown at cilium-cli/encrypt/status.go:137

func (s *Encrypt) fetchEncryptStatusFromPod(ctx context.Context, pod corev1.Pod) (models.EncryptionStatus, error) {
	cmd := []string{"cilium", "encrypt", "status", "-o", "json"}
	output, err := s.client.ExecInPod(ctx, pod.Namespace, pod.Name, defaults.AgentContainerName, cmd)
	if err != nil {
		return models.EncryptionStatus{}, fmt.Errorf("failed to fetch encryption status from %s: %w", pod.Name, err)
	}
	encStatus, err := nodeStatusFromOutput(output.String())
	if err != nil {
		return models.EncryptionStatus{}, fmt.Errorf("failed to parse encryption status from %s: %w", pod.Name, err)
	}
	return encStatus, nil
}

func nodeStatusFromOutput(output string) (models.EncryptionStatus, error) {
	if !json.Valid([]byte(output)) {
		res, err := nodeStatusFromText(output)
		if err != nil {
			return models.EncryptionStatus{}, fmt.Errorf("failed to parse text: %w", err)
		}
		return res, nil
	}
	encStatus := models.EncryptionStatus{}
	if err := json.Unmarshal([]byte(output), &encStatus); err != nil {
		return models.EncryptionStatus{}, fmt.Errorf("failed to unmarshal json: %w", err)
	}
	return encStatus, nil
}

func nodeStatusFromText(str string) (models.EncryptionStatus, error) {
	res := models.EncryptionStatus{
		Ipsec: &models.IPsecStatus{
			DecryptInterfaces: make([]string, 0),
			XfrmErrors:        make(map[string]int64),
		},
		Wireguard: &models.WireguardStatus{
			Interfaces: make([]*models.WireguardInterface, 0),

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Inspect the raw output with `kubectl exec ... -- cilium encrypt status` and compare against the expected `key: value` lines
  2. Upgrade the Cilium agent so JSON output (-o json) is valid and the text fallback is not needed
  3. If a new field has non-numeric values, update nodeStatusFromText to handle the new key explicitly
  4. Report/patch the parser in cilium-cli/encrypt/status.go if the agent format changed legitimately
Defensive patterns

Strategy: validation

Validate before calling

if !json.Valid([]byte(output)) && !strings.Contains(output, "Keys in use") {
    // output matches neither expected format; don't attempt parse
}

Type guard

func looksLikeEncryptStatusText(s string) bool {
    for _, key := range []string{"Encryption", "Keys in use", "Errors"} {
        if strings.Contains(s, key+":") { return true }
    }
    return false
}

Try / catch

res, err := nodeStatusFromOutput(output)
if err != nil {
    return fmt.Errorf("agent output unparseable; raw=%q: %w", truncate(output, 200), err)
}

Prevention

When it happens

Trigger: `cilium encrypt status` output is neither valid JSON nor well-formed text: e.g. a line like `Keys in use: not-a-number` hits strconv.Atoi failure inside nodeStatusFromText, or unexpected keys with non-numeric values in the default xfrm-error branch.

Common situations: Older or patched cilium-agent emitting changed text format; output polluted by warnings before status lines; non-English locale or new fields with textual values; unit tests feeding malformed fixtures (see Test_nodeStatusFromOutput).

Understand the failure class

Related errors


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