hashicorp/terraform · error

unexpected token after valid JSON: %v

Error message

unexpected token after valid JSON: %v

What it means

Returned by structured.ParseJson (change.go:315-328) when, after successfully decoding one JSON value, the decoder encounters a token that is not EOF — meaning the input has trailing content after a complete JSON document. ParseJson is used to unmarshal before/after/unknown/sensitive fields of plan/state changes, so malformed JSON anywhere in those fields surfaces here.

Source

Thrown at internal/command/jsonformat/structured/change.go:327

	for key, value := range values {
		out[key] = unmarshalGeneric(value)
	}
	return out
}

func ParseJson(reader io.Reader) (interface{}, error) {
	decoder := json.NewDecoder(reader)
	decoder.UseNumber()

	var jv interface{}
	if err := decoder.Decode(&jv); err != nil {
		return nil, err
	}

	// The JSON decoder should have consumed the entire input stream, so
	// we should be at EOF now.
	if token, err := decoder.Token(); err != io.EOF {
		return nil, fmt.Errorf("unexpected token after valid JSON: %v", token)
	}

	return jv, nil
}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Validate the plan/state JSON is a single well-formed document: `jq empty plan.json` (jq errors on trailing tokens).
  2. Regenerate the plan/state from terraform rather than consuming a possibly-corrupted file.
  3. If the data came from the redacted endpoint, retry the request or report the malformed payload.
  4. Fix any post-processing pipeline that concatenates or truncates JSON documents.

Example fix

# before
$ terraform show -json tfplan   # tfplan corrupted with trailing bytes
# after
$ terraform plan -out=tfplan
$ terraform show -json tfplan
Defensive patterns

Strategy: validation

Validate before calling

// Ensure a raw JSON field is a single complete document before ParseJson.
dec := json.NewDecoder(bytes.NewReader(raw))
var v interface{}
if err := dec.Decode(&v); err != nil {
    return fmt.Errorf("invalid json: %w", err)
}
if _, err := dec.Token(); err != io.EOF {
    return fmt.Errorf("trailing data after json document")
}

Prevention

When it happens

Trigger: A Change's Before/After/Unknown/Sensitive raw JSON contains more than one JSON value (e.g. two concatenated objects, or an object followed by stray characters). Most often the input comes from the HCP Terraform redacted endpoint or a corrupted/manually-edited plan or state JSON file fed to the renderer.

Common situations: Corrupted plan/state files; HCP Terraform redacted-endpoint returning malformed payloads; tools that concatenate JSON documents incorrectly when post-processing terraform output; truncated writes that left partial JSON after a valid prefix.

Understand the failure class

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/14d4a608b456ea52. Report an issue: GitHub.