Troubleshooting

How to Fix JSON Parsing Errors in ColdFusion

Overview of the Problem

JSON parsing errors in ColdFusion usually occur when using functions like deserializeJSON() to convert a JSON string into native CFML Data structures (structs, arrays, queries). An error arises when the string is not valid JSON, is encoded incorrectly, has unexpected content (such as a BOM or HTML), or when the server Configuration and code disagree about how to serialize or deserialize data.

Common error signatures include:

  • coldfusion.runtime.JSONUtils$JSONParseException: Expected …
  • Invalid JSON encountered at position …
  • The given JSON can not be parsed due to invalid characters or format.

Why it happens:

  • JSON must conform to strict Syntax (double quotes for keys/strings, no trailing commas, no comments).
  • The string may not be JSON at all (e.g., an HTML error page).
  • Character encoding issues (UTF‑8 vs. ISO‑8859‑1), BOMs, or binary content can corrupt the payload.
  • Double-encoding or incorrect serialization settings produce malformed JSON.

How JSON Parsing Works in ColdFusion

ColdFusion’s deserializeJSON() expects a valid JSON string and converts it into CFML objects:

  • JSON object -> struct
  • JSON array -> array
  • JSON string/number/bool/null -> string/numeric/boolean/null (requires null support on some versions)

Useful helpers:

  • isJSON(string): quickly checks if a string looks like valid JSON.
  • serializeJSON(value [, options]): outputs valid JSON from CFML data (queries, structs, arrays).
  • getHttpRequestData().content: raw request body for REST endpoints receiving JSON.
  • cfhttp: to fetch JSON from APIs.
See also  How to Fix ColdFusion Administrator Crashing

ColdFusion versions differ in nuance (null handling, query serialization formats, case preservation), so environment matters when Troubleshooting.


Possible Causes

Data Format Problems

  • Trailing commas: {“a”:1,} or [1,2,]
  • Single quotes instead of double quotes: {‘x’: ‘y’}
  • Comments in JSON: // comment or / comment /
  • Unescaped control characters: newlines or backslashes within strings
  • Double-encoded JSON: a JSON string that contains JSON text as a nested string and only parsed once
  • Non-JSON content: HTML error pages, XML, or server-side notices mixed with JSON
  • Invalid numbers or locale issues: “1,23” instead of 1.23

Transport and Encoding Issues

  • Wrong Content-Type header (text/html or text/plain instead of application/json)
  • Incorrect charset (ISO-8859-1 vs UTF-8)
  • Byte Order Mark (BOM) at the start of the document
  • Binary response interpreted as text (or vice versa) in cfhttp

Environment and Settings

  • Case transformation on struct keys (expecting “userId” but receiving “userid”)
  • Query serialization mismatch (array-of-structs vs column-based format)
  • Debug output or whitespace being injected into JSON responses
  • Null handling disabled (JSON nulls become empty strings on older configs)

Step-by-Step Troubleshooting Guide

Step 1: Reproduce and Capture the Exact Error

  • Wrap parsing in try/catch to capture message and detail.

cfml







  • Inspect logs: Exception.log or application logs may show JSONParseException with the failing character position.

Example log line:

coldfusion.runtime.JSONUtils$JSONParseException: Expected a ‘:’ after a key at character 42 in {“name” “Chris”}

Step 2: Verify the Incoming Payload

  • Dump or log the first 500–2000 characters of the string before parsing (ensure you do not log sensitive data).
  • Validate externally with a tool like JSONLint.
  • Use isJSON():

cfml
<cfif NOT isJSON(trim(jsonString))>


If isJSON() returns false, look for HTML, comments, trailing commas, or bad quoting.

Step 3: Check Encoding and Strip BOM

If content contains non-ASCII characters or comes from files/APIs with unknown charset:

  • Ensure strings are UTF-8.
  • Remove BOM if present.

cfml







If using cfhttp and the body is binary, decode it:

cfml
<cfif isBinary(res.fileContent)>
<cfset body = charsetDecode(res.fileContent, “UTF-8”)>



Step 4: Confirm Content-Type and Headers

On the consumer side, ensure you only parse JSON when Content-Type is application/json.
On the producer side, set headers explicitly and suppress debug/extra output:

cfml



#serializeJSON(data, false)#

The enablecfoutputonly setting helps prevent stray spaces or HTML from being emitted.

Step 5: Sanitize Non-Standard JSON (If You Cannot Fix the Source)

Typical issues to sanitize:

  • Remove comments and trailing commas if they are known and safe to strip.
  • Replace single quotes with double quotes only if you are certain they’re not inside values that need escaping.

Minimal sanitizer (use carefully):

cfml








Note: Regex-based sanitizers can break valid strings; fix the source whenever possible.

Step 6: Handle Data Type Edge Cases

  • Dates: serializeJSON/deserializeJSON may treat date strings as strings. Standardize on ISO 8601 strings (e.g., “2025-09-20T10:21:00Z”) and convert after parsing.
  • Numbers with locale commas: pass as strings and cast later.
  • Nulls: if your JSON contains null, ensure ColdFusion null support is enabled (on applicable versions) or account for conversion to empty strings.
See also  How to Resolve CFImage Processing Errors

Step 7: Address Case and Query-Format Mismatches

  • Preserve key case if needed via application-level settings (varies by version).
  • When serializing queries, ensure the format matches consumer expectations (array of structs vs. column-based). If your consumer expects array-of-structs, configure serializeJSON accordingly.

Step 8: Re-test and Add Guards

  • Add isJSON checks and descriptive error responses on API endpoints.
  • Log Content-Type, length, a hash of the body, and a snippet of the payload for future diagnostics.

Quick Cause / Solution Reference

  • Cause: Single quotes or trailing commas

    • Solution: Replace with valid JSON (double quotes; remove trailing commas). Validate with isJSON().
  • Cause: HTML or debug output mixed into the response

    • Solution: Use cfsetting showdebugoutput=”false” and enablecfoutputonly=”true”. Set proper headers.
  • Cause: BOM or wrong charset

    • Solution: Remove BOM; read/convert as UTF-8; set cfhttp charset=”utf-8″; use charsetDecode when needed.
  • Cause: Binary response treated as text (cfhttp)

    • Solution: If isBinary(fileContent), charsetDecode to UTF-8 first.
  • Cause: Double-encoded JSON (JSON string containing JSON)

    • Solution: Deserialize twice deliberately: deserializeJSON(deserializeJSON(rawJSON)) when appropriate.
  • Cause: Query serialization mismatch

    • Solution: Configure serializeJSON to output array-of-structs if that is expected.
  • Cause: Null handling differences

    • Solution: Enable null support where applicable or normalize after parsing.

Code Recipes

Parse JSON from cfhttp Safely

cfml







<cfif NOT findNoCase(“application/json”, contentType)>

<cflog application="true" file="json" text="Unexpected content-type: #contentType#; sample: #left(body, 120)#">
<cfthrow message="Upstream did not return JSON." />

<cfif NOT isJSON(body)>



Parse JSON from an Incoming Request (API Endpoint)

cfml


<cfif NOT isJSON(json)>


{“error”:”Body must be valid JSON.”}


Clean Up Common Formatting Issues (Last Resort)

cfml
<cfset raw = fileReadExpandPath(“/incoming/payload.json”, “UTF-8”)>


Serialize CF Data to JSON Correctly

cfml






SELECT id, email, created_at FROM users


#serializeJSON(qUsers, false)#

If your CF version supports queryFormat arguments or application-wide serialization settings, configure them to match your consumer.


Common mistakes and How to Avoid Them

  • Mixing HTML or whitespace into API responses:
    • Avoid implicit output. Use cfsetting enablecfoutputonly=”true” and controlled cfoutput blocks.
  • Assuming any text is JSON:
    • Check Content-Type and validate with isJSON(). Log a snippet before parsing.
  • Ignoring character encodings:
    • Always handle UTF-8 explicitly. Remove BOMs. Decode binary bodies.
  • Using single quotes or comments in JSON:
    • JSON requires double quotes and no comments. Sanitize or fix the source.
  • Double-encoding:
    • If data contains a JSON string field that itself is JSON, understand whether you need one or two deserializeJSON() calls.
  • Not handling nulls:
    • Ensure your CF environment handles nulls as you expect, or post-process fields after parsing.
  • Query serialization surprises:
    • Set query serialization mode (array-of-structs vs columns) consistently across your app.
See also  How to Fix CFMAIL Not Sending Emails

Prevention Tips / Best practices

  • Enforce JSON Standards at boundaries:
    • Reject payloads that are not Content-Type: application/json.
    • Validate with isJSON() and schema validation when possible.
  • Control output strictly:
    • showdebugoutput=”false” in production.
    • enablecfoutputonly=”true” to prevent stray output.
  • Normalize encoding:
    • Use UTF-8 throughout. Remove BOMs on ingestion. Set cfhttp charset and response headers.
  • Centralize JSON utilities:
    • Create helper functions for removeBOM(), safeDeserialize(), and consistent serialization.
  • Log smartly:
    • Log headers, sizes, hashes, and small snippets—not entire payloads.
  • Version-aware Configuration:
    • Document and standardize serializeJSON/deserializeJSON behaviors (query format, key case, null support) across environments.
  • Contract testing with APIs:
    • Use Integration tests to assert JSON structure and types for upstream/downstream services.

Key Takeaways

  • JSON parsing errors in ColdFusion are most often caused by invalid JSON Syntax, wrong content type, or encoding issues.
  • Always validate and log a small snippet of the payload before calling deserializeJSON().
  • Use UTF-8 consistently and strip BOMs; ensure responses are clean JSON without debug or HTML.
  • Configure serialization formats (especially for queries) to match consumers.
  • Build guardrails: isJSON checks, try/catch logging, strict headers, and consistent application settings.

FAQ

How can I quickly check whether a string is valid JSON before parsing?

Use isJSON(). Example:
cfml
<cfif isJSON(str)>


If it returns false, inspect for trailing commas, single quotes, comments, or non-JSON content.

Why does my API response include HTML and break JSON parsing?

ColdFusion debug output, cfdump, or stray cfoutput can inject HTML. Disable debug for production and set cfsetting showdebugoutput=”false” and enablecfoutputonly=”true”. Ensure your handler outputs only serializeJSON(…) within a controlled cfoutput block.

I’m getting errors when parsing data from cfhttp. What should I check?

  • Confirm Content-Type is application/json.
  • Ensure correct charset (use charset=”utf-8″ and charsetDecode if body is binary).
  • Remove BOMs and trim whitespace.
  • Log the first 200 characters of the body for diagnostics.

How do I serialize queries as an array of structs instead of the default format?

Many ColdFusion versions support serializeJSON(query, false) to get array-of-structs. Alternatively, check your version’s documentation for queryFormat options or application serialization settings, and standardize this across the app.

What should I do if the JSON contains comments or trailing commas that I cannot fix at the source?

Prefer to fix the source. If that’s impossible, implement a careful sanitizer to remove comments/trailing commas before parsing, and add tests to ensure you do not break valid JSON strings.

About the author

Aaron Longnion

Aaron Longnion

Hey there! I'm Aaron Longnion — an Internet technologist, web software engineer, and ColdFusion expert with more than 24 years of experience. Over the years, I've had the privilege of working with some of the most exciting and fast-growing companies out there, including lynda.com, HomeAway, landsofamerica.com (CoStar Group), and Adobe.com.

I'm a full-stack developer at heart, but what really drives me is designing and building internet architectures that are highly scalable, cost-effective, and fault-tolerant — solutions built to handle rapid growth and stay ahead of the curve.