Troubleshooting

Connection and API

Ping fails — API not reachable

Symptoms: Test API returns a network error or timeout (e.g. WinHTTP 12029 — cannot connect or 12007 — name not resolved).

  1. Open the API URL in a browser — you should see {"success":false,"message":"No action specified"}. An HTML error page or connection refused means the URL or server is the problem.
  2. Verify the URL includes the full path to edbapi.php (e.g. https://example.com/edbapi.php).
  3. Check that port 80/443 is not blocked by a local firewall.
  4. For HTTPS, verify the server certificate is valid and trusted from the client machine.

HTTP 401 — API key rejected

Symptoms: All actions fail with HTTP 401.

Check API_KEY in config.php. Enter the matching value in the API Key field on the Remote Configuration tab. If API_KEY is intentionally empty, leave the application field blank.

HTTP 400 — database connection failed

Symptoms: Test DB returns an error; log shows HTTP 400 — Connection failed: ... with a PDO error.

  1. Verify host, port, username, password, and database name.
  2. Check that the MySQL user has the required privileges (SELECT, INSERT, UPDATE, CREATE, DROP, ALTER) on the target database.
  3. If PHP and MySQL are on separate hosts, verify that MySQL allows connections from the PHP server’s IP.
  4. Check edb2mysql-api.log on the server for the full PDO error (located in private/ alongside config.php, or wherever LOG_FILE is defined in config.php).

HTTP 403 — IP not allowed

Symptoms: All actions fail with HTTP 403.

Add the client machine’s IP to ALLOWED_IPS in config.php, or set ALLOWED_IPS to [] to allow all IPs.

Non-JSON response — PHP error or error page

Symptoms: Log shows [E4004] with an excerpt of the unexpected response body; or a related code such as [E4002] (timeout) or [E1018] (memory limit) with an actionable hint.

The application classifies non-JSON server responses automatically. Many common cases produce a specific code and message:

What the server returned Log code Log message
HTTP 408 or HTTP 504 E4002 HTTP timeout — use LIMIT or increase max_execution_time
PHP max_execution_time exceeded E4002 PHP max_execution_time exceeded — use LIMIT or increase max_execution_time in php.ini
PHP memory_limit exceeded E1018 PHP memory_limit exceeded — use LIMIT or increase memory_limit in php.ini
Truncated JSON (server killed mid-response) E4002 server response was truncated — use LIMIT or increase limits
Unrecognised body E4004 plain-text excerpt of the response

When E4004 appears, the log message includes an HTML-stripped excerpt of the body. If that does not identify the cause:

  1. Open the API URL in a browser to see the raw PHP error.
  2. Check the PHP error log on the server.
  3. Verify that edbapi.php and config.php are syntactically valid.
  4. Confirm that the pdo_mysql PHP extension is installed and enabled.

Data Migration

“batch send failed” — rows not inserted

Symptoms: Log shows WARNING: Table X: batch send failed — N row(s) at offset Y..Z not inserted. On servers running PHP v175 or later, the warning also includes [row: col=val, ...] identifying the specific row that triggered the server-side error (PK columns when the table has a primary key; otherwise all non-BLOB columns). Use this to locate the problematic value in the source EDB table.

Causes: The web server returned an error page (503, 502) instead of a PHP response; or API_ENABLED = false in config.php.

  1. Check the web server error log.
  2. Click Start / Resume — migration resumes from the last committed offset.
  3. If 503 errors recur on large tables, contact the hosting provider about increasing pm.max_children (PHP-FPM) or equivalent.

Duplicate rows after migration

Cause: The table has no primary key. Re-running migration inserts all rows again — no unique constraint exists for conflict detection.

Truncate the target table before re-running (via the SQL Console or Reset selected). The Pre-Migration Analysis dialog flags tables without a primary key as a Warning.

Resume inserts wrong rows after interruption

Cause: No primary key. Without a PK, EDB does not guarantee the same row order between separate SELECT executions. The resume mechanism skips rows by offset count, not by row identity — different rows may be fetched at the same offset if physical order changed.

Truncate the target table and restart migration for the affected table. Adding a PK to the EDB table eliminates this problem.

504 Gateway Timeout during script execution

Cause: The DDL script contains many statements or slow operations that exceed the web server’s gateway timeout.

  1. Split the script into smaller sections and run them separately from the SQL Console.
  2. Ask the hosting provider to increase fastcgi_read_timeout (nginx) or ProxyTimeout (Apache) to at least 300 seconds.

Row count mismatch — “Verification FAILED”

Cause Remedy
One or more batches failed Check the log for batch send failed; click Start / Resume to retry.
No PK — migration re-run without resetting Truncate the target table and restart.
MySQL strict mode rejected rows that EDB accepted silently See below.
Debug mode was active Run a full migration with Debug Mode disabled.

Strict mode causes batch INSERT to fail

Symptoms: Log shows batch send failed; Remote Configuration panel shows Strict: Yes; server log shows Data too long for column or Out of range value for column.

Cause: STRICT_TRANS_TABLES or STRICT_ALL_TABLES is active. EDB silently accepts values that strict mode rejects.

  1. Check edb2mysql-api.log (in private/ alongside config.php) for the column name and offending value.
  2. If you have SYSTEM_VARIABLES_ADMIN privileges, disable strict mode via the SQL Console for the duration of the migration:
-- Disable strict mode (restore original value after migration)
SET GLOBAL sql_mode = REPLACE(@@GLOBAL.sql_mode, 'STRICT_TRANS_TABLES', '');
SET GLOBAL sql_mode = REPLACE(@@GLOBAL.sql_mode, 'STRICT_ALL_TABLES',   '');
  1. Alternatively, correct the offending values in EDB, truncate the target table, and restart.

BLOB and CLOB Handling

BLOBs are NULL for an entire table

Cause: The table has no primary key. Without a PK, BLOB values above the inline threshold are written as NULL by design (flagged as a Warning by the Pre-Migration Analysis dialog).

Add a primary key to the EDB table before migration.

A single large BLOB was committed as NULL — connection or timeout error at blob_commit

Symptoms: Log shows ERROR [E4001] (connection failed) or ERROR [E4002] (timed out) on action blob_commit, followed by WARNING: Abandoned blob_commit session (UUID=...); partial server file auto-removed within 48 h. The affected BLOB column is NULL in MySQL.

Cause: The web server’s FastCGI/proxy read timeout expired while PHP was executing the MySQL UPDATE. The web server closed the connection before PHP sent the JSON reply.

  1. Fix the affected row manually: extract the BLOB from EDB and apply a direct MySQL UPDATE using a MySQL client tool.
  2. To prevent recurrence, increase fastcgi_read_timeout (nginx) or ProxyTimeout (Apache) to at least 300 seconds.

BLOB viewer shows truncated content

Cause: The cell exceeded Max KB in the SQL Console toolbar.

Click Download Full Content in the BLOB viewer. If the button is not visible (no PK columns in the result, or aliased column), increase Max KB and re-run the query.

BLOB viewer shows empty content

Cause: PHP ran out of memory while fetching a row with a large BLOB, or the BLOB exceeded MAX_RESULT_BUFFER_MB in config.php.

Add a WHERE clause to reduce the result set, or increase MAX_RESULT_BUFFER_MB in config.php. Check the server-side log for PDO buffer overflow errors.

CLOB field contains garbled text or Base64 characters

Symptoms: After querying a table that has CLOB columns, some fields show unreadable content such as dGVzdCBzdHJpbmc= or similar Base64-encoded strings instead of the expected text. Only affects values that exceeded the OOB KB threshold (visible in the SQL Console toolbar, or the InlineBlobMaxBytes property in the library).

Cause: A bug in EDBMMUtils v16 and earlier: CLOB cells stored as server-side temp files (values exceeding the OOB threshold) were written to the local EDB field as the raw Base64 string instead of the decoded text. Binary BLOB columns were not affected — only text CLOB columns. Fixed in EDBMMUtils v17.

Remedy: - In the SQL Console: re-run the query that produced the result. The current version decodes OOB CLOB values correctly. - In the library (TMMScript.Execute), if you are using an assigned Table that persists across calls: re-run Execute to overwrite the affected rows with correct values. If the table was populated by code using EDBMMUtils v16 or earlier, identify affected rows by checking CLOB fields for Base64 patterns (letters, digits, +, /, and = padding only, no spaces or punctuation).

BLOB chunk upload failed — E4001 or E4002 in log

Symptoms: Log shows [E4001] (connection failed) or [E4002] (timed out) during data migration of a table with BLOB/CLOB columns. Migration may stop or report the batch as failed.

Cause: A network error or timeout occurred while uploading a BLOB chunk to the server (the binary data is sent in pieces via HTTP multipart). This is a transport failure, not a PHP-level error.

  1. Check network stability between the workstation and the hosting server.
  2. If the error is E4002 (timeout): increase fastcgi_read_timeout (nginx) or ProxyTimeout (Apache) — see the Server Configuration Checklist below.
  3. Click Start / Resume — migration resumes from the last committed offset. The partially uploaded BLOB will be retried from the beginning for that row.

Note: If the log shows [E4006] (HTTP multipart upload failed) rather than E4001/E4002, the chunk reached the server but was rejected — check upload_max_filesize and post_max_size in php.ini.

Orphaned temp files on the server after aborted migration

Cause: A BLOB chunk upload was in progress when migration was aborted; the partially assembled temp file was not deleted.

Manually delete the blobuploads/ directory inside the configuration folder (the private/ folder containing config.php) via FTP/SFTP or a file manager.

Note: the server-side log file (edb2mysql-api.log) and the _tmp/ directory for script and result temp files are also located in this configuration folder (outside the webroot), not inside the PHP/ webroot folder. If you upgraded from a version older than v184 of edbapi.php without a LOG_FILE definition, a stale edb2mysql-api.log may still exist at PHP/edb2mysql-api.log — it can be safely deleted. The directory is recreated automatically on the next migration.

Alternatively, if you have HTTP access to the API, send action=blob_cleanup to delete all files under blobuploads/ programmatically — for example from the SQL Console using a REST client, or via a direct HTTP POST:

{ "action": "blob_cleanup" }

Server Configuration Checklist

Minimum recommended configuration for reliable migration of databases with large BLOBs:

Setting Location Recommended value
fastcgi_read_timeout nginx vhost ≥ 300 s
ProxyTimeout / Timeout Apache vhost ≥ 300 s
max_execution_time php.ini / .user.ini 3600 or 0
max_input_time php.ini only 3600 or -1
post_max_size php.ini / .user.ini ≥ 64 MB
upload_max_filesize php.ini / .user.ini ≥ 64 MB
memory_limit php.ini ≥ 256 MB
max_allowed_packet MySQL server ≥ 64 MB

max_input_time is evaluated before any PHP code runs and cannot be changed via ini_set. It must be set in php.ini or an .htaccess php_value directive.

The application reads post_max_size, upload_max_filesize, and memory_limit from the server after connection and configures BLOB and batch limits automatically.

See Also

(C) 2026 Easygate, Lda