January 2026

Qlik Replicate: And we’re back to EBCDIC problems again

EBCDIC – my perpetual nightmare

Before I have written about EBCDIC; and the tribulations I have come across

With the post festive system haze still on – I spent a full day trying to work out another encoding problem that came up in our exception table.

Let me take you on a journey.

It starts with MS-SQL.

We have Qlik Replicate replicating data from a DB2/zOS system into a MS-SQL system.  I was investigating why there were inserts missing from the target table and exploring the dbo.attrep_apply_exceptions table I notice a bunch of INSERTS from another table in the exception table:

/*
CREATE TABLE dbo.destination
(
	add_dte numeric(5, 0) NOT NULL,
	chg_dte numeric(5, 0) NOT NULL,
	chg_tme varchar(6) NOT NULL,
	argmt varbinary(10) NOT NULL,
	CONSTRAINT pk_destination PRIMARY KEY CLUSTERED
	(
		argmt
	) WITH (DATA_COMPRESSION = ROW) ON [PRIMARY]
) ON [PRIMARY]
*/

INSERT INTO [dbo].[destination] ( [add_dte],[chg_dte],[chg_tme],[argmt])  VALUES (46021,46021,'151721', 0x35333538C3A302070000);

I thought it would be a good place to start by substituting the failed insert into a temp table and using the temp table to investigate downstream data flows.

So:

DROP TABLE IF EXISTS ##temp_destination;

SELECT *
INTO ##temp_destination
FROM [dbo].[destination]
WHERE 1 = 0;

INSERT INTO ##temp_destination ( [add_dte],[chg_dte],[chg_tme],[argmt]) VALUES (46021,46021,'151721', 0x35333538C3A302070000);

But as I was substituting the temp table into objects downstream – I was just getting logical errors. Comparing the temp table against other data that already existed dbo.destination; it looked not right.

Working Upstream

I thought it would be a good place to start by substituting the failed insert into a temp table and using the temp table to investigate downstream data flows.

Since we just merged a system into our DB2/zOS system; my initial thought it was a corrupted record coming from a merge process. I contacted the upstream system owners and asked for help.

They came back and said the record was fine and the issue must be in the QR system converting the data wrong. This did not make sense – if there was a issue in the QR system; it would have been picked up in testing. Also, there would be lots of exceptions in dbo.attrep_apply_exceptions. I had confidence that QR was handling it right.

Not trusting what the DB2/zOS team had told me; I created a temp Qlik task to dump out that table into a test database.

Using the other values in the record; I could look the record up in the table and compare the two.

For the field argmt it came back as:

0xF5F3F5F846022F00000F

This looked nothing like what was in the exception table.

EBCDICy epiphany

Of course – it took a while; but it finally struck what was going on.

The field argmt had sections encoded in EBCDIC. This was getting brought across as bytes to MS-SQL. There was a downstream trigger that was failing in the MS-SQL database. But when it was getting written out into the exception table; it was getting written as ASCII (or possibly Windows-Latin) encoding.

(Only showing start of bytes as this is what we use downstream)

With me just copying the insert statement and using it as is; I was treating ASCII bytes as EBCDIC; causing all sorts of logical errors downstream.

Where to from here?

I’m going to raise this abnormality with Qlik. I am not sure if it is a “bug” or a “feature”; but good to get clarification on that point.

I also will need to educate our users on how to interpret the values in dbo.attrep_apply_exceptions so not to stumble into mistakes that I did.

As for fixing the data itself – since we have the full dump of data from the table and the data is slow moving; I can substitute the values from the data dump into the problem INSERT statement.

This should allow it to run just fine.

Qlik Replicate Schedules – a CRON with an extra field?

Introduction

To make our lives easier migrating Qlik Replicate tasks from one environment to another; I am looking how to migrate Qlik Replicate schedules.

So far by GitLab pipelines we can migrate tasks and endpoint; but schedules we must do manually.  Quite often we forget to manually create the schedules as they are not as obvious component compared to tasks and endpoints.  If you move to a new environment and your task is not there, well that is a no brainer.  If your endpoint is not there; your task will not migrate.

But schedules are something that lurks in the background; inconsistently created when we rush to put them in when we realise the Qlik task did not run when it was meant to.

Plan

Using the python API, we can export all the items from a Qlik Replicate server with the export_all method.  In the returned Json file will be the schedule details like this:

{
    "name": "DEV_S004_GCS_DLA",
    "command_id": 25,
    "schedule": "0 1 * * * *",
    "command_requests": {
        "cleanlogs_req": {
            "server": {},
            "task": {},
            "fts": {}
        },
        "logfilerollover_req": {},
        "execute_req": {
            "task": "",
            "operation": "EXECUTE_OPERATIONS_BOTH",
            "flags": "FRESH"
        },
        "stoptask_req": {
            "task": ""
        }
    },
    "task": "DEV_T222_DL_LENDING_DLA",
    "is_local_time": true
}

The idea is to modify the Json for the schedule to match the environment we are migrating to; put the schedule into a blank server Json template and use the import_all

 method to upload the new schedules to the destination server.

The Cron does not look right…

Looking over the exported Json; the cron syntax did not look right.  It had six fields instead of the expected five.

"schedule": "0 1 * * * *"

This confused me for a while as I haven’t come across a cron like this before.

After coming up with no results searching Qlik’s documentation; I created some test schedules to try and determine what the sixth field is used for.

Ahh. After a short while I found the answer.

If the schedule is a “Once off” run; the sixth field is used for “Year”.

Here is an example below:

{
	"name":	"Test",
	"command_id":	25,
	"schedule":	"30 15 7 1 * 2026",
	"command_requests":	{
		"cleanlogs_req":	{
			"server":	{
			},
			"task":	{
			},
			"fts":	{
			}
		},
		"logfilerollover_req":	{
		},
		"execute_req":	{
			"task":	"",
			"operation":	"EXECUTE_OPERATIONS_BOTH",
			"flags":	"FRESH"
		},
		"stoptask_req":	{
			"task":	""
		}
	},
	"task":	"EIT_T002_OB_RFSB_ACCT_02",
	"enabled":	false
}