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 examples3://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
- Back up the application database (
lilt_devby default), or at minimum the tables listed below. - Quiesce writers. Scale
front,converter-core,file-translation-core,tm-core,job-core, andfile-job-coreto zero, or pick a quiet window. In-flight RabbitMQ messages carry full URIs, so let the queues drain (rabbitmqctl list_queues) before rewriting. - Run the census. Every prefix group should show the old bucket or
NULL. Record the counts. - Run the rewrite inside one transaction. Each
UPDATEis preceded by aCOUNT; after the update the same count must be zero. - 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.
- Update the bucket name in every configuration location listed at the end, redeploy, and re-run the census. Only the new bucket should remain.
lilt cannot match lilt-prod.
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 itsscheme://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 wrotes3:/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.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.
JSON and text columns
Run a statement only if its census count was greater than zero. Check the column type first withSHOW 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.
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.*:xliffFileIdandtransUnitIdare XLIFF attributes.NeuralBatchTranslationJobs.request:dataFilePathis a bare key with no bucket.- Neural model storage: bare keys under
model_storage_v4/andtrained/; 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.bucketfor converter, tm, job, workflow, file-job, file-translation, segment, memory, and the rest. - file-job and job:
onpremValues.env.BUCKETNAME. - core-api and dataflow:
BUCKETNAMEinenv. - 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 oflilt, so it must be added explicitly. - neural:
<alias>.onpremValues.config.bucketandinit.outputPath(s3://<new-bucket>/trained/). - core chart init containers:
init.outputPathandfilePathsfor lexicon and file-job (s3://<new-bucket>/lexicon-data/,s3://<new-bucket>/tesseract/).
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 reportsWrong 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.
