Troubleshooting

How to Resolve Lucee vs Adobe ColdFusion Behavior Differences

Overview of the Problem

Applications written in CFML may behave differently when running on Lucee versus Adobe ColdFusion (ACF). These differences can show up as runtime errors, inconsistent query results, unexpected date/locale formatting, different scope resolution, or Features that work on one engine but not the other. The root cause is that Lucee and ACF are distinct CFML engines with different defaults, compiler behaviors, admin settings, extension ecosystems, and, in some cases, language semantics. Understanding where they diverge—and how to standardize Configuration and code—allows you to resolve issues quickly and build portable, engine-agnostic CFML.


Why Lucee and Adobe ColdFusion Behave Differently

Runtime and Defaults

  • Lucee runs on Tomcat by default, often using BonCode AJP with IIS/Apache; ACF also uses Tomcat but ships with its own web server connector.
  • Default admin settings differ (null/empty behavior, search implicit scopes, locale/charset, white-space management, request timeout).
  • Extensions and libraries (PDF, Image, Excel/Spreadsheet) may be built-in on ACF but require installation in Lucee via the Extension Store.

Language and Tag/Script Parity Differences

  • Some tags and functions exist in one engine or behave slightly differently (e.g., QoQ functions, date parsing, cfhttp headers, cfmail TLS, image/pdf operations).
  • Defaults for “null support,” implicit scope resolution, and “tag islands in script” may differ.
  • SQL types, cfqueryparam null handling, and dbtype=”query” behavior are not always identical.

Admin and Connector Differences

  • ACF Admin vs Lucee Admin: settings live in different places, with different naming and scopes (server vs web context in Lucee).
  • Connector technology: ACF Web Server Configuration Tool vs Lucee’s BonCode/mod_cfml setup may lead to different request headers, encodings, and path mappings by default.
See also  How to Fix ColdFusion Scheduled Task Not Running

Quick reference: Common Causes and Solutions

  • Cause: Missing or different extensions (e.g., PDF, S3, Mail).

    • Solution: Install matching Lucee extensions; confirm library versions align across engines.
  • Cause: Different null/empty handling in cfqueryparam and functions.

    • Solution: Use cfqueryparam null=”true” with explicit cfsqltype and defensive code paths.
  • Cause: Locale and date parsing differences (LSParseDateTime, ParseDateTime).

    • Solution: Set consistent locale/timezone, use ISO-8601 formats, and validate with createODBCDateTime.
  • Cause: Scope resolution differences (variables, CGI, URL/FORM).

    • Solution: Enable consistent “search implicit scopes” settings; reference local/arguments explicitly.
  • Cause: QoQ Syntax/function support differences.

    • Solution: Simplify QoQ; cast types; avoid engine-specific functions; test with dbtype=”query”.
  • Cause: Character encoding differences in requests/responses.

    • Solution: Set pageencoding, request charset, and connector encoding consistently.
  • Cause: Connector mappings and virtual hosts differences affecting CGI.PATH_INFO and getContextPath().

    • Solution: Align connector configuration (BonCode/WSCT), verify rewrite rules and mappings.

Step-by-Step Troubleshooting Guide

1. Confirm the Environment and Compatibility Settings

  • Verify engine versions (e.g., Lucee 5.x/6.x vs ACF 2018/2021/2023).
  • In Lucee Admin, check:
    • Language/Compiler: CFML dialect vs Lucee dialect.
    • Compatibility options (e.g., “Search Implicit Scopes,” “Allow per App Settings”).
    • Null support and white-space management.
  • In ACF Admin, confirm:
    • Request timeout, default charset/locale, per-application settings.

Tip: Use CommandBox to spin up sandboxed Lucee and ACF servers with the same codebase for reproducible tests.

2. Reproduce with Minimal Code

  • Reduce the problem to a self-contained test case.
  • Create a small CFM/CFM script that isolates the behavior (e.g., a single cfquery or date parse).
  • Validate in both engines; log input and output.

3. Check Admin and Application.cfc Config

  • Standardize settings via Application.cfc to reduce admin discrepancies:
    • this.charset, this.locale, this.timezone
    • this.mappings, this.datasource, this.sessionManagement
    • this.scriptProtect, this.requestTimeout
  • Ensure per-application settings are enabled in both engines.

4. Validate Datasource and SQL Differences

  • Confirm DSN config (driver type, connection string, time zone, ANSI nulls).
  • Normalize cfqueryparam usage; ensure cfsqltype is correct and null handling is explicit.
  • Compare SQL logs; run the generated SQL directly against the DB to check differences in trimming, casting, or parameter binding.

5. Inspect Request/Session/Scope Behavior

  • Confirm session/cookie settings (secure, httponly, samesite).
  • Check “search implicit scopes” and ensure you explicitly use local/arguments variables.
  • Validate that CGI and Path variables match expectations across connectors.

6. Review Date/Locale/Encoding

  • Log variables: getLocale(), getTimeZone(), charsetEncode(), getEncoding().
  • Enforce ISO-8601 for dates: 2024-12-31T23:59:59Z.
  • Use LSParseDateTime with explicit locale where needed.

7. Check File Paths, Mappings, and Case Sensitivity

  • Normalize mappings in Application.cfc and Admin.
  • On case-sensitive filesystems, ensure tag/CFML case is consistent.
  • Use expandPath and canonicalize paths to avoid differences across OS/engine.

8. Evaluate Security/Sandboxing and Blocked Functions

  • Check if cfexecute, file system access, or Java interop is restricted.
  • Align sandbox settings (ACF Enterprise) and Lucee Security/Restrictor rules.
  • Audit permissions for temp directories, mail spool folders, and logs.
See also  How to Fix ColdFusion Lock Contention Errors

9. Inspect Logs and Stack Traces

  • Lucee logs: /lucee/tomcat/lucee-server/context/logs or web-context/logs.
  • ACF logs: cfusion/logs (or instance-specific).
  • Compare stack traces for missing classes, permissions, or configuration differences.

Sample Lucee error:

ERROR PageContextImpl – column [user_id] not found in Query; Query of Queries requires proper type casting.
at lucee.runtime.type.QueryImpl.getColumn(QueryImpl.java:…)

Sample ACF error:

coldfusion.sql.QueryTable$QueryTableException: Variable USER_ID is undefined in the query result set.

10. Automation with cfconfig and CommandBox

  • Use cfconfig export/import to replicate Admin settings across engines.
  • Script your servers:
    • Install Lucee extensions.
    • Configure datasources, mail, mappings.
    • Version-control your server.json/.cfconfig.json.

Code and Configuration Examples

Application.cfc alignment

component {
this.name = “MyApp”;
this.sessionManagement = true;
this.sessionTimeout = createTimeSpan(0,2,0,0); // 2 hours
this.requestTimeout = createTimeSpan(0,0,60,0);
this.charset = “UTF-8”;
this.locale = “en_US”;
this.timezone = “UTC”;
this.scriptProtect = “all”; // align XSS protection

// Datasource names must match Admin configs
this.datasource = “MyDSN”;

// Normalize scope searching in Lucee (Admin may allow override)
// Lucee Admin > Language & Compiler > “Search Implicit Scopes” = Always / Never
// In ACF, avoid implicit scope reliance and prefix variables explicitly.

this.mappings[“/lib”] = expandPath(“/app/lib”);
this.javaSettings = {
loadPaths = [ expandPath(“/app/lib/java”) ],
reloadOnChange = true
};

function onApplicationStart(){
// Self-checks for parity
application.engine = server.coldfusion.productName; // “Lucee” or “ColdFusion”
}
}

Null handling and cfqueryparam

Cross-engine-safe pattern for nullable values:



INSERT INTO users(email, created_at)
VALUES(
,

)

  • Ensures both Lucee and ACF pass NULL when userEmail is empty.

Query of Queries (QoQ) differences

  • Cast types and avoid engine-specific functions.

<cfset q = queryExecute(“SELECT id, trim(name) as name, cast(age as integer) as age FROM people”, [], {datasource=this.datasource})>


SELECT id, name, age
FROM q
WHERE age >= 18
ORDER BY name

  • If your QoQ fails on a function, pre-compute the value in the original DB query or add a computed column.

Date parsing and locale




  • Avoid relying on LSParseDateTime with server-default locale.

Mail and Scheduled tasks

  • Mail server differences: TLS/SSL flags may differ.

<cfmail to=”test@site.com” from=”noreply@site.com” subject=”Hello”
server=”smtp.example.com” port=”587″ username=”u” password=”p” useTLS=”true”>
Test

  • Scheduled tasks: verify Admin-level definitions vs. application-scheduled tasks.

Connector config (IIS/Apache)

  • ACF: use Web Server configuration Tool.
  • Lucee: BonCode AJP or mod_cfml. Check BonCodeAJP13.settings:




  • Ensure request character encodings and forwarded headers are consistent between engines.

Common mistakes and How to Avoid Them

  • Relying on implicit scope resolution. Fix: Always qualify variables with local/arguments/session/url/form/etc.
  • Assuming built-in Features exist on both engines. Fix: On Lucee, install extensions for PDF, Spreadsheet, S3, ORM (if needed), etc.
  • Using ambiguous date/time strings. Fix: Standardize to ISO-8601 and UTC; explicitly parse/format.
  • Skipping cfsqltype and null in cfqueryparam. Fix: Always specify cfsqltype and null explicitly.
  • Ignoring connector differences. Fix: Align BonCode/WSCT configs, request encoding, and rewrite rules.
  • Not enabling per-application settings. Fix: Set critical runtime settings in Application.cfc rather than relying on server-wide defaults.
  • Overusing QoQ with complex functions. Fix: Simplify QoQ or move logic into the database layer.

Prevention Tips / Best practices

  • Standardize via Application.cfc:
    • Set charset, locale, timezone, requestTimeout, sessionManagement.
    • Define mappings and datasources consistently.
  • Use CommandBox for parity testing:
    • Spin up Lucee and ACF containers with the same code and environment variables.
  • Automate Admin config with cfconfig:
    • Export from one engine; import to another; commit JSON to Version control.
  • Write engine-agnostic CFML:
    • Avoid engine-specific tags/functions or guard with engine checks (server.coldfusion.productName).
    • Prefer script Syntax with explicit scoping and typed arguments.
  • Normalize date/time/number handling:
    • Persist UTC in the DB; convert at the edges; use ISO-8601.
  • Strengthen database interactions:
    • Use cfqueryparam everywhere; define explicit types; handle NULLs carefully.
  • Log proactively:
    • Add structured logging around queries, dates, encodings, and external calls.
  • Pin library and extension versions:
    • Track versions in Deployment scripts; verify after upgrades.
  • Security parity:
    • Align sandbox/restrictor rules; explicitly allow necessary functions; secure mail and file access.
  • Document differences:
    • Maintain a “Lucee vs ACF” compatibility document with known patterns and resolutions.
See also  How to Fix Application Scope Memory Leaks

Key Takeaways / Summary Points

  • Behavioral discrepancies often come from different defaults and admin settings, not just code differences.
  • Make behavior explicit in Application.cfc and avoid relying on server-wide defaults.
  • Handle cfqueryparam nulls, date/locale, and scope resolution explicitly to achieve cross-engine consistency.
  • Use CommandBox and cfconfig to reproduce and align environments.
  • Install necessary Lucee extensions and pin versions to match ACF capabilities.

FAQ

How can I quickly tell whether a behavior difference is configuration or code?

Start by replicating with a minimal test under both engines. If the minimal code behaves differently, compare Application.cfc and Admin settings (charset, locale, null support, implicit scopes, request timeout). If aligning these fixes the issue, it’s configuration; otherwise, inspect engine-specific feature usage or missing extensions.

Why does my Query of Queries work on ACF but fail on Lucee (or vice versa)?

QoQ function support and type coercion can differ. Pre-cast columns (e.g., numeric fields), avoid engine-specific functions, and simplify the QoQ. Alternatively, compute complex expressions in the database query and keep the QoQ for filtering/ordering only.

Dates are parsed differently across engines. What’s the safest approach?

Use ISO-8601 strings and parse with explicit patterns. Set this.locale and this.timezone in Application.cfc to stable values (e.g., en_US and UTC). Avoid relying on server defaults or ambiguous date formats.

My mail or PDF code works on ACF but not on Lucee. What should I check first?

Confirm the corresponding Lucee extension is installed and configured. For mail, ensure TLS/SSL flags and credentials match; verify truststore certificates if needed. For PDF operations, ensure the PDF extension and dependencies (fonts, binaries) are present and accessible.

Can I make Lucee imitate a specific ColdFusion version?

Lucee provides compatibility options and a CFML dialect setting in the Admin that can reduce differences. It won’t perfectly emulate every ACF version, but aligning compiler settings, null support, and scope behavior—combined with Application.cfc settings—gets you close. For exact parity, test under both engines using CommandBox and adjust code where necessary.

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.