Skip to main content
From release N+2 (the first release that ships the ENG-32953 migration) stored object references no longer carry a scheme or bucket, and renaming the bucket or switching between MinIO, S3 and GCS is a configuration change only, provided every service is configured with the same bucket. This procedure applies to releases up to N+1, and to a JSON or text column that still embeds a URI.

Overview

LILT stores object references in the database as full URIs that include the bucket name, for example s3://lilt/prod/converter-service/.... Every service that reads one of these URIs checks that the bucket segment equals the bucket it is configured with, and refuses the read if it does not. Copying the objects into a bucket with a different name and pointing the configuration at it is therefore not enough: every reference written before the move still names the old bucket and fails outright. The symptoms are immediate and affect only pre-existing work. New uploads and new exports succeed, while anything created before the rename fails with File export failed, a 500 or Local URI error on download, a TMX re-import failure, or Wrong bucket name from the neural services. Because the errors show a plausible-looking S3 path, the wrong bucket segment is easy to miss. This article covers rewriting the stored URIs so an existing installation can move to a bucket with a new name. It applies after the objects have been copied key-for-key, for example by following Migrate Object Storage (MinIO to S3). If you can keep the bucket name identical across the move, do so and skip this procedure entirely. The table and column inventory below was verified against LILT 5.3.4. Other releases may add columns; the census in the first step is the check.

Order of Operations

  1. Back up the application database (lilt_dev by default), or at minimum the tables listed below.
  2. Quiesce writers. Scale front, converter-core, file-translation-core, tm-core, job-core, and file-job-core to zero, or pick a quiet window. In-flight RabbitMQ messages carry full URIs, so let the queues drain (rabbitmqctl list_queues) before rewriting.
  3. Run the census. Every prefix group should show the old bucket or NULL. Record the counts.
  4. Run the rewrite inside one transaction. Each UPDATE is preceded by a COUNT; after the update the same count must be zero.
  5. Run the JSON and text column rewrites only for columns whose census count was greater than zero. On a stock 5.3.x installation every one of those is expected to be zero.
  6. Update the bucket name in every configuration location listed at the end, redeploy, and re-run the census. Only the new bucket should remain.
Set the two values once per session so the statements below can be pasted as written. Both end with a slash so that lilt cannot match lilt-prod.
The LIKE CONCAT(@old, '%') anchor cannot match a URI that already carries the new bucket, so re-running any statement is harmless.

Census

Read-only. Group every URI column by its scheme://bucket prefix.

Permanent references

These are read for source download, re-export, TMX re-import, estimates, and PDF re-export. Every row must be rewritten.
UserResources.xliff is named like a content column but holds the imported-XLIFF URI for translation memory and termbase resources.

Regenerable references

The application can regenerate these, but it reads the stored value first (the Download button, hard-delete cleanup), so rewrite them too.

Legacy single-slash form

Older releases wrote s3:/bucket/... with one slash, and core still accepts it. Expect zero.

JSON and text columns

These columns could embed a URI. No 5.3.4 writer puts one there, so expect zero everywhere. Rewrite only what the census finds.
If the neural services run with storageType: minio (the stock 5.3.x value), their internal URIs use the minio:// scheme instead of s3://. Repeat the two neural counts with @old set to the minio:// form.

Rewrite

Run as one transaction. Documents.fileLocation goes first because front derives new export URIs from it. Compare each count before and after; after must be zero.
If the census found legacy single-slash rows, normalise them to the double-slash form of the new bucket in the same transaction:

JSON and text columns

Run a statement only if its census count was greater than zero. Check the column type first with SHOW CREATE TABLE: a JSON-typed column needs the CAST(... AS JSON) form so MySQL re-validates the document, while a TEXT column takes plain REPLACE. The replacement string contains no quotes or backslashes, so the JSON stays valid.
The same two forms apply to ScheduledEvents.payLoad, FileJobs.jobParams, UserNotifications.data, ExternalModels.providerConfig, ConnectorJobs.args, and Connectors.args. The neural tables need care. NeuralBatchTranslationRequests.request holds in-flight work only and is deleted on completion, and the batch workers cache these rows in memory at startup. Prefer draining the neural.batch.* queues so the rows finish or fail before the cutover. If rows must be rewritten, scale the neural batch workers to zero first.

Columns to Leave Alone

These look like paths but are not bucket URIs. Do not rewrite them.
  • Users.imageURL: an HTTP profile picture URL from the identity provider.
  • Documents.xliff: inline XLIFF content on legacy rows, not a path.
  • Segments.*: xliffFileId and transUnitId are XLIFF attributes.
  • NeuralBatchTranslationJobs.request: dataFilePath is a bare key with no bucket.
  • Neural model storage: bare keys under model_storage_v4/ and trained/; the bucket comes from configuration.
  • Redis upload hand-off keys hold full URIs but live only for one request. No flush is required.

Configuration That Must Change

After the rewrite, every location that names the bucket must say the new name. A single global value can be shadowed by a stale per-service override, so check each one in the installer values file (lilt/values.yaml in the on-prem installer).
  • Core services: <alias>.onpremValues.app.args.bucket for converter, tm, job, workflow, file-job, file-translation, segment, memory, and the rest.
  • file-job and job: onpremValues.env.BUCKETNAME.
  • core-api and dataflow: BUCKETNAME in env.
  • front: front.onpremValues.config.front_configmap_values.awsS3Bucket. This key is not present in the installer values file by default and falls back to the chart default of lilt, so it must be added explicitly.
  • neural: <alias>.onpremValues.config.bucket and init.outputPath (s3://<new-bucket>/trained/).
  • core chart init containers: init.outputPath and filePaths for lexicon and file-job (s3://<new-bucket>/lexicon-data/, s3://<new-bucket>/tesseract/).
Redeploy, then re-run the census. Only the new bucket prefix should remain.

Troubleshooting

New work downloads but anything created before the move fails: the rewrite was skipped or ran against the wrong database. Re-run the census. Downloads fail for one service only: that service still carries the old bucket in a per-service override. Compare the rendered configuration of the failing service against a working one. Neural reports Wrong bucket name: the neural config.bucket or init.outputPath was not updated, or the neural tables still hold old URIs from work that was in flight at the cutover.