Greg Joiner
06/09/2026, 2:19 PMENGINE=OLAP
DUPLICATE KEY(raw_import_timestamp)
PARTITION BY date_trunc('day', raw_import_timestamp)
PROPERTIES (
"compression" = "LZ4",
"datacache.enable" = "true",
"datacache.partition_duration" = "1 DAY",
"fast_schema_evolution" = "true"
);
here is the structure of our second level 'C' tables.
PRIMARY KEY(event_time, region, car_row_id)
PARTITION BY date_trunc('day', event_time)
ORDER BY (event_time)
PROPERTIES (
"compression" = "LZ4",
"datacache.enable" = "true",
"enable_persistent_index" = "true",
"persistent_index_type" = "CLOUD_NATIVE"
);
The issue is when we run this:
SHOW PROC '/transactions/events/running';
All of the results have a 'CommitTime', but we see many records without a 'PublishTime' from 2 days ago and no , and some from 2 days ago that have a 'PublishTime' but still no 'FinishTime'
What can be the cause and how can we fix it?Rocky
06/09/2026, 2:26 PMCOMMITTED (waiting for Publish) or PUBLISHED (waiting for Finish) for multiple days—typically indicates a bottleneck in the Metadata/Transaction management or Object Storage (Azure Blob) latency.
Since you are running in shared-data mode (CN + MS Blob), here are the most likely causes and the steps to fix them:
1. FE Thread Pool Exhaustion (Most Likely for "Stuck" Txns)
If transactions have a CommitTime but no PublishTime, the FE may have failed to submit the "Publish Version" task to the CNs, or the internal task queue is full.
* Check FE Logs: Search fe.warn.log or fe.log for strings like rejected from agent-task-pool.
* Cause: StarRocks uses a thread pool (agent-task-pool) to send tasks to CNs. If you have many tablets or very high-frequency small loads, this pool (default 4096) can become exhausted.
* Fix: Increase the thread pool size in `fe.conf`:
properties
# Requires FE restart
agent_task_resubmit_wait_time_ms = 1000
# Monitor if this is full
Also, check if lake_publish_version_max_threads (default 512) is sufficient for your load concurrency.
2. Version Continuity Gap
In shared-data mode, StarRocks requires strictly sequential versions to publish. If transaction N is stuck or fails, transactions N+1, N+2, etc., will stay in COMMITTED state and never become VISIBLE.
* Diagnosis: Run SHOW PARTITIONS FROM <table_name> and compare VisibleVersion with NextVersion. If there is a gap (e.g., Visible=100, Next=105), transactions 101-104 are likely stuck.
* Cause: Often caused by a failed schema change or a CN crash during a critical publish phase.
* Fix: Check fe.log for partition.getVisibleVersion() + 1 != version. You may need to manually abort the oldest stuck transaction if it hasn't timed out, or in extreme cases, contact support if a metadata repair is needed.
3. Azure Blob Storage Latency & Small Files
The drop from 20 minutes to 4 hours suggests I/O amplification or Metadata overhead on Azure Blob.
* The PK Table Issue: Your second-level 'C' table uses a 64-byte string (car_row_id) in the Primary Key. Large keys increase the size of the Cloud Native Persistent Index. Every insert requires reading/writing these index files to Azure Blob.
* The Bucketing Issue: If your PARTITION BY is very granular (e.g., date_trunc('day')) and you have many buckets, you create thousands of small metadata files on Azure Blob per transaction.
* Fixes:
* Batch your inserts: Ensure you aren't doing many small INSERT statements. 19M records should ideally be one or a few large transactions.
* Optimize Bucketing: Ensure each tablet (bucket) is ~1GB to 10GB. If tablets are too small, metadata operations on Azure Blob will crawl.
* Enable File Bundling (v4.0+): Since you are on 4.09, ensure file bundling is enabled to reduce the number of small files written to Azure:
sql
ADMIN SET FRONTEND CONFIG ("enable_paimon_file_bundle" = "true"); -- if applicable
-- and check table properties for "file_bundle"
4. Compaction Backlog
If background compaction tasks are stuck, they can hold locks or consume the lake_publish_version_max_threads pool.
* Check Compactions:
sql
SHOW PROC '/compactions';
-- Check if many tasks have StartTime but no FinishTime
* Fix: If you see thousands of stuck compactions, you can temporarily throttle them to let ingestion catch up:
sql
ADMIN SET FRONTEND CONFIG ("lake_compaction_max_tasks" = "100"); -- lower this if it's too high
Recommended Diagnostic SQLs
Run these to pinpoint where the delay is:
1. Check for rejected tasks: grep "rejected" fe.log
2. Check partition version lag:
```sql
SELECT DB_NAME, TABLE_NAME, PARTITION_NAME, VISIBLE_VERSION, NEXT_VERSION
FROM information_schema.partitions_metaRocky
06/09/2026, 2:26 PMAlive in SHOW COMPUTE NODES;. If a CN is flapping, the FE will keep trying to send publish tasks to it and timeout.
Note on v4.09: As this is a very recent version, ensure that lake_enable_batch_publish_version is set to true (it should be by default) to minimize RPC calls to Azure Blob.
References
• administration/management/FE_configuration.md
• administration/management/BE_configuration.mdGregM
06/09/2026, 4:01 PMRocky
06/09/2026, 4:01 PMCommitTime but no PublishTime (or no FinishTime), look at these metrics on the Leader FE:
* starrocks_fe_txn_publish_schedule_latency_ms: If this is high, the transaction is committed but waiting in the FE's internal queue. This usually means the agent-task-pool is saturated.
* publish_version_queue_count: Monitor this value. If it is consistently high (e.g., > 100), the FE is failing to push "Publish Version" tasks to the CNs fast enough.
* starrocks_fe_txn_publish_execute_latency_ms: If this is high, the CN nodes are receiving the tasks but taking a long time to execute them (likely due to the storage latency below).
* starrocks_fe_txn_publish_ack_latency_ms: If this is high, the CNs have finished the work, but the FE is taking a long time to record the final metadata update back into its image/journal.
──────────
3. Metrics to Diagnose Slowness (20m -> 4h)
Given your switch to PK tables with a 64-byte string on Azure Blob, these metrics on the CN nodes are critical:
* fslib_s3_single_upload_latency: (Even on Azure, this often maps to Starlet's object upload metrics). If the P99 latency is > 100ms, your inserts will slow down significantly as every "version" must be flushed to the blob.
* pk_index_sst_read_error_total / pk_index_sst_write_error_total: High values here indicate that the Cloud Native Persistent Index is failing to communicate with Azure Blob.
* update_primary_index_bytes_total: Monitor the memory usage of your primary key index. If this is growing too large, it may cause the CN to thrash or swap.
* fslib_cache_hit_ratio: Since you are using datacache.enable = true, a low hit ratio (< 80%) means your queries and PK index lookups are constantly hitting Azure Blob, which is orders of magnitude slower than the local cache.
──────────
4. Prevention and Thresholds
To prevent this in the future, set up alerts for these specific thresholds:
Metric | Threshold (Alert if...) | Action
publish_version_queue_count | > 200 | Increase FE lake_publish_version_max_threads.
fslib_read_io_latency (P99) | > 500ms | Check Azure Blob storage account limits or throttling.
lake_compaction_score | > 100 | Ingestion is faster than compaction; consider slowing down inserts.
starrocks_fe_txn_publish_latency_ms | > 60s | Investigate network/storage latency between FE and CNs.
Why it might be happening now
With 60M records/day and a 64-byte string PK, your Cloud Native Persistent Index creates many small files on Azure Blob.
* If your Azure Blob Storage Account is reaching its IOPS or throughput limit, the Publish Version phase (which writes the final metadata and index files) will stall.
* Prevention: Ensure your 19M record inserts are bundled into a single transaction. Many small INSERT statements will multiply the metadata overhead on Azure Blob exponentially.
References
• best_practices/primarykey_table.md
• table_design/table_types/primary_key_table.mdRocky
06/09/2026, 4:01 PMGregM
06/09/2026, 5:46 PMFail to publish partition 2799322 error Fail to publish version for tablets:[[2799332, 2799328, 2799325, 2799326, 2799329, 2799324, 2799327, 2799331, 2799330, 2799333, 2799323]], error msg: delvec inconsistent tablet:2799323 rssid:66 #old:366278 #add:26526 #new:392800 old_v:27 v:32, host: kube-starrocks-cn-1...
it's bizzare because our ETL process ran for several days with no issue and processed billions of records then hit this and got jammed upRocky
06/09/2026, 5:46 PMdelvec inconsistent ... #old:366278 #add:26526 #new:392800 is a low-level data integrity check failure within StarRocks' Primary Key storage engine.
The Cause: Delete Vector Mismatch
StarRocks uses Delete Vectors (delvec) to track which rows in older files have been logically deleted by newer updates. When applying a new batch of data (Publish phase), the system performs this check:
Existing Delete Markers (old) + New Delete Markers (add) == Total Markers in New Version (new)
In your case: 366278 + 26526 = 392804. However, the system calculated 392800.
The discrepancy is 4 rows. This mismatch causes the LOG(FATAL) or a failed publish task because the system refuses to write inconsistent metadata.
This typically happens due to a race condition between a write transaction and a background compaction task in shared-data mode. While you are on v4.09, which includes many fixes, this specific inconsistency suggests that the Cloud Native Persistent Index and the Metadata service on Azure Blob have diverged for those specific tablets.
──────────
How to Fix It
1. Immediate Recovery (Partition Level)
Because this is a metadata inconsistency on specific tablets, the cleanest way to "un-jam" the system is to remove the corrupted partition and reload it.
* Identify the partition: Your error mentions partition 2799322.
* Action:
sql
-- Drop the specific partition that is stuck
ALTER TABLE <table_name> DROP PARTITION <partition_name>;
-- Then reload the data for that period.
_Note: Since your RAW table is Duplicate Key (no corruption there), you can simply re-run the INSERT INTO C_table SELECT ... FROM RAW_table for that day._
2. Rebuild the Persistent Index
If dropping the partition is not ideal, you can try forcing StarRocks to rebuild the index files on Azure Blob, which may resolve the calculation error:
sql
-- This forces the CN to re-read the data and re-generate the index
ALTER TABLE <table_name> REBUILD INDEX;
(Check your specific version's support for this command in shared-data mode; if it's not supported, dropping the partition is the standard path).
3. Adjust Concurrency Settings
To prevent the race condition between write and publish in the future, try disabling "Batch Publish" which is often where these race conditions occur:
sql
-- Run on FE to reduce the risk of batch-publish races
ADMIN SET FRONTEND CONFIG ("lake_enable_batch_publish_version" = "false");
Note: This might slightly increase the time it takes to finish a transaction, but it is much safer for data consistency in high-concurrency environments.
4. Address the 64-byte String PK
You mentioned a 64-byte string unique identifier in your Primary Key.
* Observation: Long strings in a Primary Key significantly increase the size and complexity of the Persistent Index.
* Recommendation: If possible, hash this car_row_id into a BIGINT or use a shorter ID. Large string keys are more prone to hitting internal memory/buffer limits during the apply phase, which can contribute to these types of inconsistencies.
Summary of Why Queries Slower (20m -> 4h)
The slowness is a direct symptom of this metadata jam. When a transaction is "stuck" in the publish phase:
1. Version Gaps: New transactions cannot become visible because they must wait for the stuck version (e.g., v27) to finish.
2. Lock Contention: The FE keeps the transaction record open, holding metadata locks that slow down other SHOW or INSERT commands.
3. Retry Storm: The CNs and FE are likely retrying the failed publish in the background, consuming IOPS on your Azure Blob storage and CPU on your CNs.
Next Step: Check fe.log for the keyword inconsistent and failed to publish. If you see hundreds of these, dropping and recreating the affected partition is the most reliable way to clear the metadata corruption.
ReferencesGregM
06/09/2026, 5:48 PMRocky
06/09/2026, 5:48 PMdelvec inconsistent error you're seeing is a known, albeit rare, state where the metadata tracking deleted rows (Delete Vectors) becomes out of sync with the actual data files.
Here is why this typically happens "out of the blue" and what the root causes are:
1. The "Out of the Blue" Trigger: Compaction vs. Publish
This error is almost always caused by a race condition between a background Compaction task and a foreground Publish task (the final stage of your INSERT).
* Why now? After several days of ingestion, the number of "versions" or small files in your 'C' table likely reached a threshold that triggered a large-scale background compaction.
* The Conflict: If a compaction task merges files while a high-concurrency insert is trying to calculate which rows to delete in those same files, a calculation mismatch can occur. In shared-data mode, if one node fails to update the metadata service (on Azure Blob) atomically, the system gets stuck with an inconsistent "view" of the data.
2. Version Gaps in Shared-Data Mode
In a shared-data (Cloud Native) architecture, StarRocks requires strict version continuity.
* If transaction N hits the delvec inconsistent error, it fails to "Publish."
* Transactions N+1, N+2, etc., will successfully "Commit" but stay in a COMMITTED state forever because they are waiting for the "gap" at version N to be filled.
* Result: This is why your transactions are taking 2 days; they aren't actually working—they are queued behind a broken version.
3. Azure Blob Latency & 64-byte Keys
Your use of a 64-byte string as a Primary Key significantly amplifies this risk:
* Index Size: A 64-byte PK makes the Cloud Native Persistent Index much larger. Every time a new batch is "Applied," StarRocks must fetch and update this index from Azure Blob.
* I/O Pressure: If Azure Blob experiences even a momentary latency spike or throttling while updating these large index/delvec files, the internal transaction timeout can trigger, leading to a partial metadata write—the primary cause of "inconsistency."
──────────
How to Fix and Prevent
Step 1: Clear the Blockage (The "Clean Slate")
Since the metadata is inconsistent, the FE cannot "heal" it automatically.
* Identify the bad partition: (From your error: 2799322).
* Drop and Reload: The fastest fix is to ALTER TABLE ... DROP PARTITION .... This clears the bad metadata. Then, re-insert that day's data from your RAW (Duplicate Key) table.
Step 2: Tune for Stability
To prevent this race condition, adjust these settings in your fe.conf (requires restart):
properties
# Reduce the concurrency of publish tasks to ensure atomicity
lake_publish_version_max_threads = 32
# (If supported in your specific 4.x sub-version)
# Disable batching if you see frequent delvec errors
lake_enable_batch_publish_version = false
Step 3: Optimize the Primary Key
If you continue to use a 64-byte string as a PK:
* Bucketing: Ensure your tablet count is not too high. If each partition has hundreds of tablets, you are creating thousands of small delvec files on Azure Blob, which increases the chance of a write failure. Aim for ~1GB-5GB per tablet.
* Batching: Instead of frequent small inserts, group your 19M records into 1 or 2 large batches. This reduces the number of metadata "Publish" events and the chance of colliding with background compaction.
Summary of Diagnosis
The slowness (20m -> 4h) is likely due to the FE and CNs endlessly retrying the "Publish" for the inconsistent version 27, which blocks all subsequent transactions. Once you drop the offending partition, your ingestion speed should return to normal.GregM
06/10/2026, 12:19 AMRocky
06/10/2026, 12:19 AMdelvec inconsistent error and how to optimize it:
1. The "Commit Serialization" Bottleneck
In StarRocks shared-data mode, the Frontend (FE) serializes transaction commits at the partition level to ensure data consistency.
* The Conflict: When Query A and Query B both target the same partition, Query B must wait for Query A to finish its "Publish Version" phase.
* The Risk: If Query A is large (e.g., your 19M records), it takes time to update the Persistent Index and write the Delete Vectors to Azure Blob. If Query B starts immediately, the FE may try to "batch" these versions or the CN nodes may face lock contention while trying to read the index that Query A is still finalizing.
2. High "Compaction Score"
Every time you write to a partition, you create a new "version" (a set of small files).
* The Problem: If you write to the same partitions multiple times in a short window, you quickly accumulate many small versions.
* The Result: This triggers Compaction (the background process that merges these versions). In shared-data mode, if compaction is running on the same tablets you are currently writing to, it increases the likelihood of the race condition that causes the delvec inconsistent error.
* Detection: Check SHOW PROC '/transactions/<db_id>/running';. If you see the message Partition's compaction score is larger than 100.0, delay commit, your ETL is outrunning the background maintenance.
3. Recommendations for your ETL
To keep your process stable with your 64-byte string PKs on Azure Blob:
* Consolidate Writes: Instead of several queries writing to the same partitions in sequence, try to use a single INSERT INTO ... SELECT ... that joins or unions all your source data first. One large transaction is significantly safer and faster than five smaller ones.
* Increase Compaction Concurrency: Since you are on shared-data, the CN nodes need more "muscle" to keep up with the metadata churn.
properties
# On CN nodes (be.conf)
compact_threads = 8 # Increase from default
* Use "Batch Publish" cautiously: As mentioned before, if you have high-frequency writes to the same partitions, disabling the FE's internal batching of version publishing can prevent the specific delvec calculation error you saw:
sql
ADMIN SET FRONTEND CONFIG ("lake_enable_batch_publish_version" = "false");
* Check Tablet Health: Use SHOW TABLET FROM <table_name> to see how many versions (VersionCount) exist per tablet. If this number is consistently > 50-100, you need to slow down the write frequency or increase compaction resources.
Summary
The pattern isn't "forbidden," but it is high-pressure. Your delvec inconsistent error was essentially a "collision" between two updates (or an update and a compaction) that both tried to modify the same Delete Vector on Azure Blob at the same time. Consolidating your ETL into fewer, larger transactions is the best architectural fix.
References
• table_design/table_types/primary_key_table.md
• faq/operation_maintenance_faq.mdGregM
06/10/2026, 12:43 AMRocky
06/10/2026, 12:44 AM#old + #add != #new). This calculation is driven by the Persistent Index (the map that says "Key X is in Segment Y").
_ If the Persistent Index file on Azure Blob was corrupted or didn't sync properly during a previous operation, it will tell the CN: _"You need to delete 392,804 rows."*
* But when the CN looks at the actual data segments, it only finds 392,800.
* Why it recurs after a drop/recreate: If your ETL process involves cross-partition updates (e.g., an incoming row has a primary key that exists in a different partition), StarRocks must go to that old partition to mark the old row as deleted. If the index has a logic bug handling your 64-byte string keys at scale, it will keep generating these small mismatches.
3. The "Lake Batch Publish" Race
There is a known issue in some 3.x and 4.x versions where the FE tries to "batch" the publishing of multiple transactions to increase throughput.
* When multiple concurrent INSERT or UPDATE operations target the same set of tablets, the batch-publish logic can occasionally double-count or miss delete markers in the metadata.
* This explains why it worked "briefly" after your recreate and then failed again: As soon as your ETL ramped back up to high concurrency, the race condition returned.
──────────
Recommended "Nuclear" Fix & Investigation
Since dropping the partition didn't permanently fix it, you need to stabilize the metadata layer:
1. Disable Batch Publishing (Highest Priority):
This is the most common fix for recurring delvec inconsistent errors in Lake mode. It forces the FE to publish versions one by one, eliminating the race condition.
sql
ADMIN SET FRONTEND CONFIG ("lake_enable_batch_publish_version" = "false");
2. Clear the Persistent Index Cache:
It is possible your CN nodes are holding a "stale" version of the index in their local disk cache (storage/persistent_index/).
* If possible, restart a CN node one by one. When it comes back up, it will pull a fresh (and hopefully consistent) version of the index from Azure Blob.
3. Check for "Global" Key Collisions:
Are you sure your incoming data doesn't have keys that already exist in that 2-day-old partition? If your ETL is "moving" data between partitions (e.g., updating a record's date which changes its partition), this triggers complex metadata updates that are prone to this error.
4. Check FE Logs for "Conflict":
Search your fe.log specifically for the tablet_id mentioned (2799323). Look for any messages saying compaction conflict or version already exists. This will confirm if background compaction is the culprit.Rocky
06/10/2026, 12:44 AMGregM
06/10/2026, 12:50 AMRocky
06/10/2026, 12:50 AMcn.conf. The index is stored under the directory specified by storage_root_path.
* Inside that path, look for a folder named persistent (e.g., /opt/starrocks/storage/persistent/).
* The PVC check: Run kubectl get pod <cn-pod-name> -o yaml and look at the volumeMounts section. If the path matching your storage_root_path is mounted to a persistentVolumeClaim, then the index is on a PVC and will survive restarts.
2. Why a restart isn't enough
When a CN pod restarts, it looks at that persistent directory. If it finds existing index files, it simply reloads them.
* If the "4-row mismatch" metadata error is baked into those local index files, the CN will just reload the same corrupted state.
* In shared-data mode, the "Source of Truth" is technically on Azure Blob, but the local CN cache can get "stuck" if the local file is present but inconsistent with the remote version.
3. How to Force a "Clean Slate" (Recreate)
To truly force the node to rebuild the index from the remote storage (or from scratch), you must manually remove the local cache before the restart.
The "Clean Slate" Procedure:
1. Scale down the CN deployment to 0 (or stop the specific CN pod).
2. Delete the index files on the PVC. You can do this by mounting the PVC to a temporary "maintenance" pod or by exec-ing into the pod before it shuts down:
bash
# From inside the CN pod
rm -rf /opt/starrocks/storage/persistent/*
_(Note: Ensure you only delete the contents of the persistent folder, not the entire storage_root_path if you also have Data Cache you want to keep.)_
3. Scale up the CN deployment.
4. Important Configuration Check
Check if your cluster is configured to store the index only in the cloud (v3.3.2+). If you have this set, the local PVC is just a temporary cache:
sql
-- Check this in your FE/BE configs
ADMIN SHOW FRONTEND CONFIG LIKE '%persistent_index%';
If you see a setting like lake_persistent_index_type = CLOUD, the CN will automatically try to sync from Azure Blob. However, if it's LOCAL, the CN relies heavily on the files on that PVC.
Summary
If you see the delvec inconsistent error and you have PVCs, restarting the pod is like rebooting a computer without clearing the cache. To fix it, you must delete the contents of the storage/persistent/ directory on the PVC so the node is forced to pull fresh metadata from the FE and Object Storage.
References
• table_design/table_types/primary_key_table.md
• administration/management/BE_configuration.md
• deployment/shared_data/azure.md
References
• using_starrocks/caching/block_cache.md
• data_source/data_cache_troubleshooting.md
• deployment/upgrade.md
• using_starrocks/caching/query_cache.md
• administration/management/BE_configuration.md
• deployment/downgrade.mdGregM
06/10/2026, 11:24 AMRocky
06/10/2026, 11:24 AMLOCAL (Default in older versions/configurations): The index is stored entirely on the CN node's local disk (storage_root_path/persistent/). In Kubernetes, if this path is on a PVC, the CN pod will reload the exact same index files upon restart.
* CLOUD_NATIVE (Recommended for Shared-Data): The index "Source of Truth" is stored on your object storage (Azure Blob). The local disk is used only as a cache.
Why this matters: If a metadata mismatch (like your "4-row" error) gets written into the local index files on the PVC, restarting the pod won't help. The pod wakes up, sees the existing index on the PVC, and says, "Great, I don't need to rebuild anything," and continues using the corrupted metadata.
2. How to Check Your Index Type
Run the following command to see how your table is configured:
sql
SHOW CREATE TABLE <your_table_name>;
Look for these properties:
* "enable_persistent_index" = "true"
* "persistent_index_type" = "LOCAL" <-- If you see this, the PVC is likely the issue.
3. Why CLOUD_NATIVE is the Solution
For shared-data clusters, StarRocks highly recommends using CLOUD_NATIVE persistent indexes.
* Self-Healing: If a node restarts or a cache is lost, the CN simply pulls the latest consistent index from Azure Blob.
* Consistency: Since the index is versioned alongside your data in the cloud, it is much harder for a single node's local disk state to cause a cluster-wide "delvec inconsistent" error.
4. How to Fix It
If you find you are using LOCAL on a PVC, you have two options:
Option A: Switch to Cloud Native Index (Recommended)
You can alter the table to use the cloud-native index. This will move the index "Source of Truth" to Azure Blob:
sql
ALTER TABLE <table_name> SET ("persistent_index_type" = "CLOUD_NATIVE");
Note: This might trigger a background task to upload the index; monitor SHOW ALTER TABLE COLUMN to see progress.
Option B: The "Clean Start" (Manual PVC Wipe)
If you must stay with LOCAL, you need to manually invalidate the PVC cache to force a rebuild from the data:
1. Stop the CN pod(s).
2. Mount the PVC to a "debug" pod or use a script to delete all files inside the persistent/ directory.
3. Restart the CN pod.
4. StarRocks will see the index is missing and will be forced to rebuild it by scanning the data segments on Azure Blob, which should resolve the "4-row" mismatch.
Summary
The PVC is doing its job (preserving data), but in this specific case, it’s preserving a "corrupted" or "out-of-sync" local view of your metadata. Switching to "persistent_index_type" = "CLOUD_NATIVE" is the architectural fix to prevent the PVC from being a single point of metadata failure.
References
• best_practices/primarykey_table.md
• administration/management/BE_configuration.md
• faq/shared_data_faq.md
References
• best_practices/primarykey_table.md
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
• table_design/indexes/inverted_index.mdGregM
06/10/2026, 11:26 AMORDER BY (event_time)
PROPERTIES (
"compression" = "LZ4",
"datacache.enable" = "true",
"enable_persistent_index" = "true",
"persistent_index_type" = "CLOUD_NATIVE"
);Rocky
06/10/2026, 11:27 AMCLOUD_NATIVE persistent indexes, the "Source of Truth" for your primary key index lives in your Azure Blob storage, not on the local PVC. However, the recurring error on a 2-day-old partition suggests that the metadata for that partition is being modified (or failing to be modified) even when you aren't explicitly loading data into it.
Here is why a 2-day-old partition is failing and how to stop the cycle:
1. The "Global" Primary Key Effect
In a StarRocks Primary Key table, uniqueness is enforced across the entire table, not just the current partition.
* The Scenario: If your new data today contains a primary key that already exists in that 2-day-old partition, StarRocks must go back to the old partition and mark the old row as "deleted" (via a Delete Vector).
* The Error: Your error (#old + #add != #new) is a metadata checksum failure. It means that when the FE/CN tried to update the delete markers for that 2-day-old partition, the math for the "total deleted rows" didn't add up compared to what was previously recorded.
2. Why it keeps happening (The "Batch Publish" Race)
In shared-data (Lake) mode, StarRocks attempts to optimize performance by batching the "Publish" phase of multiple transactions.
* There is a known issue where high-concurrency updates can cause the FE to incorrectly sum up the delvec counts when multiple transactions try to "delete" rows from the same old tablet at the same time.
* The Fix: Disable batch publishing to force strict, one-by-one metadata updates. This is the most successful fix for recurring delvec inconsistent errors in Lake mode.
sql
ADMIN SET FRONTEND CONFIG ("lake_enable_batch_publish_version" = "false");
3. Background Compaction
Even if no writes happen, StarRocks runs background compaction on old partitions to merge small files.
* If a compaction task for that 2-day-old partition was scheduled recently and hit a bug while updating the CLOUD_NATIVE index on Azure, the partition's metadata becomes "poisoned."
* You only see the error when you next attempt a write that triggers a PK lookup in that partition.
4. The PVC "Ghost" Cache
Even with CLOUD_NATIVE, the CN nodes use the local disk (your PVC) as a cache for those index files.
_ If a CN node has a corrupted _cached* version of the index on its PVC, it might keep using it even after a restart.
* To rule this out: You should perform a "Deep Clean" on at least one CN node. Scale it down, manually delete the contents of the storage/persistent/ directory on the PVC, and scale it back up. This forces it to pull a fresh, verified index from Azure Blob.
Summary Checklist to Resolve:
1. Run Repair: Try to let StarRocks fix the metadata state for that specific partition by rolling it back to the last known healthy version:
sql
ADMIN REPAIR TABLE <table_name> PARTITION (<old_partition_name>);
2. Disable Batch Publish: Run the ADMIN SET FRONTEND CONFIG command mentioned above.
3. Check for Cross-Partition Upserts: Verify if your ETL is sending rows that would overwrite data in those older partitions. If so, the metadata pressure on those partitions is much higher than you'd expect for "idle" data.
4. Verify StarRocks Version: If you are on a version earlier than v3.2.10 or v3.3.3, there were significant fixes for CLOUD_NATIVE index consistency that address this exact "4-row mismatch" logic.
Recommendation: If disabling lake_enable_batch_publish_version doesn't stop the recurrence within 24 hours, it is likely a bug in the compaction logic for your specific version, and you should check the <http://be.INFO|be.INFO> logs for "compaction" related errors on that specific tablet_id.
References
• administration/management/resource_management/Replica.mdRocky
06/10/2026, 11:27 AMGregM
06/10/2026, 12:45 PMlake_enable_batch_publish_version to falseRocky
06/10/2026, 12:45 PMlake_enable_batch_publish_version to false changes how StarRocks commits (publishes) data transactions to your shared-data cluster. While it is often used as a fix for the "delvec inconsistent" metadata errors you are seeing, there are specific trade-offs:
1. The Performance Trade-off (Throughput)
The primary reason this setting exists is to handle high-concurrency writes (e.g., hundreds of small Stream Loads per second).
* With true (Default): The Frontend (FE) bundles multiple completed transactions into a single "Publish RPC." This significantly reduces the overhead on the FE and the metadata service.
* With `false`: Every single transaction must wait for its own dedicated RPC to finish. In high-concurrency environments, this can create a bottleneck at the FE, leading to "Transaction Queue Full" errors or much lower total ingestion throughput (KB/s).
_ _Note: In benchmarks, disabling this can drop throughput by 5x–8x during heavy parallel loading.*
2. Visibility Latency vs. Throughput
* Visibility Latency: When set to false, an individual transaction might actually become "visible" for querying slightly faster because it doesn't have to wait for other transactions to fill a batch.
* Overall Ceiling: However, because the system is doing more "work" per transaction, the total number of transactions the cluster can handle per minute decreases.
3. Impact on FE Stability
* If you have a very high volume of small loads, setting this to false will increase the CPU and Thread usage on your FE. Monitor the lake_publish_version_max_threads usage if you make this change.
4. Why it fixes your error
The "delvec inconsistent" error often stems from a race condition or a logic error in how the FE calculates the cumulative "Delete Vector" count when it tries to merge metadata for 10 different transactions at the exact same moment.
By setting this to false, you are essentially forcing StarRocks to serialize these updates, ensuring that each transaction's metadata is built strictly on top of the one before it.
Summary Recommendation
* If you have moderate load: You likely won't feel any negative impact. Setting it to false is a very safe way to ensure data consistency while you investigate the root cause of the metadata mismatch.
* If you have extreme real-time load: You may see your ingestion speed slow down. In that case, the long-term solution is to upgrade to a version (like v3.2.10+ or v3.3.3+) where the batching logic for CLOUD_NATIVE indexes was significantly patched, allowing you to turn batching back on safely.
References
• administration/management/FE_configuration.md
• knowledge/usage/load/shared_data_batch_ingestion.md
• best_practices/primarykey_table.md
• administration/management/BE_configuration.md
• data_source/datalake_faq.md
• administration/management/FE_configuration.md
• administration/management/FE_configuration.md
• administration/management/FE_configuration.md
• administration/management/FE_configuration.md
• administration/management/FE_configuration.md
• knowledge/usage/load/shared_data_batch_ingestion.mdRocky
06/10/2026, 12:45 PMGregM
06/10/2026, 12:47 PMRocky
06/10/2026, 12:47 PMfalse remains the primary "safety switch" for the following reasons:
1. It Eliminates Commit-Time Race Conditions
The error usually happens during the Publish phase, where the Frontend (FE) calculates the new metadata state. When lake_enable_batch_publish_version is true (the default), the FE tries to merge metadata for multiple concurrent transactions into a single update. In complex Primary Key scenarios—especially involving older partitions being updated by new "upserts"—this batching logic can occasionally hit a race condition that results in the "4-row mismatch" math error.
By setting it to false, you force StarRocks to serialize these updates, ensuring each transaction is published strictly one-by-one, which eliminates the potential for a batching math error.
2. Is there a Performance Penalty in 4.0.9?
In 4.0.9, the FE is significantly more optimized than in the 3.x series. While setting this to false will increase the number of RPC calls, the 4.x FE can handle a higher volume of individual publishes than older versions.
* Recommendation: If your ingestion rate is under 50 Stream Load jobs per minute, you likely won't notice any performance degradation at all.
* High Load: If you are doing hundreds of small loads per minute, monitor your FE CPU; you might need to slightly increase the interval between your load batches to compensate for the lost batching efficiency.
3. How to "Clean" the 2-Day-Old Partition
Because you are using CLOUD_NATIVE, the mismatched metadata is now likely "committed" to your Azure Blob metadata logs. Simply changing the setting might not fix the existing mismatch on that 2-day-old partition. You should perform a manual repair:
sql
-- This forces the FE to re-sync the metadata state for that partition
ADMIN REPAIR TABLE <table_name> PARTITION (<partition_name>);
4. Why it happened on 4.0.9
There was a specific fix in the 4.0.x branch (#71672) related to how get_tablet_stats repeatedly reloads TabletMetadata for Primary Key tablets. While 4.0.9 contains many fixes, the "delvec inconsistent" logic is notoriously sensitive to high-concurrency "Delete-then-Insert" patterns.
Summary of your next steps:
1. Set the config: ADMIN SET FRONTEND CONFIG ("lake_enable_batch_publish_version" = "false");
2. Repair the old partition: Run ADMIN REPAIR on the partition that is currently failing.
3. Check Compaction: If the error still pops up, check if lake_compaction_max_tasks is set too high, which might be putting too much concurrent pressure on the metadata service.
References
• administration/management/FE_configuration.md
• release_notes/release-4.0.md
• best_practices/primarykey_table.md
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_REPAIR.md
References
• administration/management/FE_configuration.md
• knowledge/usage/load/shared_data_batch_ingestion.md
• release_notes/release-4.0.md
• sql-reference/System_variable.mdGregM
06/10/2026, 12:55 PMstarrocks_fe_txn_publish_schedule_latency_ms in the grafana dashboards, am I missing it or is it not present?Rocky
06/10/2026, 12:55 PMstarrocks_fe_txn_publish_schedule_latency_ms is indeed present in StarRocks 4.0.x, but it is likely missing from your dashboard for two specific reasons:
1. It is disabled by default
In version 4.0, StarRocks introduced a more granular way to report transaction metrics. To prevent overhead, these metrics are not reported unless you explicitly define which "groups" of transactions you want to track.
You need to set the following FE configuration (this can be done dynamically):
sql
ADMIN SET FRONTEND CONFIG ("txn_latency_metric_report_groups" = "stream_load,routine_load,insert,compaction");
* Note: Since you are in Lake (shared-data) mode, including compaction is highly recommended, as background compaction also uses the transaction/publish pipeline.
2. It is only reported by the Leader FE
This metric is only exposed by the Leader FE node.
* If your Grafana dashboard is looking at a specific Follower FE or using an aggregate that doesn't filter for the leader, you may see "No Data."
* In your Prometheus query, ensure you filter for is_leader="true".
How to verify it exists
Once you have set the config above, you can verify the metric is being generated by hitting the FE metrics endpoint directly:
bash
curl http://<LEADER_FE_IP>:<HTTP_PORT>/metrics | grep starrocks_fe_txn_publish_schedule_latency_ms
Why this metric matters for your issue
Since you are debugging delvec inconsistent errors and considering disabling `lake_enable_batch_publish_version`:
* High Schedule Latency: If this metric is high (e.g., > 100ms), it means transactions are queuing up waiting to be published.
* The Impact of your change: If you set lake_enable_batch_publish_version to false, you will likely see this specific metric increase, because the FE can no longer "cheat" by bundling multiple transactions into one publish task. It confirms the "bottleneck" trade-off we discussed.
Summary: Update your txn_latency_metric_report_groups config, and the metric should appear in Prometheus/Grafana shortly after.
References
• administration/management/monitoring/metrics.md
• administration/management/FE_configuration.md
• release_notes/release-4.0.md
References
• administration/management/monitoring/metrics.md
• administration/management/FE_configuration.mdGregM
06/10/2026, 1:00 PMRocky
06/10/2026, 1:00 PMstarrocks_fe_txn_publish_schedule_latency_ms and its related transaction metrics were introduced in v4.0, they are often grouped into the following sections:
1. Shared-data Dashboard (Recommended)
If you are using the official shared-data dashboard template (available in the StarRocks GitHub extra/grafana folder), look for a row titled "Publish Version" or "Ingestion / Loading".
* Panel Name: Usually titled "Publish Version Latency" or "Transaction Publish Phase Latency."
* What it shows: It typically visualizes the breakdown of the publish phase, including the "Schedule" (wait time) and "Execute" (active time) components.
2. FE Dashboard
In the standard FE dashboard, these metrics are often found under the "Transaction" or "Metadata Management" section.
* Panel Name: Look for "Transaction Publish Schedule Latency" or a heatmap/quantile graph showing "FE Transaction Latency (by Phase)."
Why they might still be missing from the UI
Even if the metrics exist in Prometheus (after setting txn_latency_metric_report_groups), they won't appear in Grafana if your dashboard template is from an older version (e.g., v3.x).
To resolve this:
1. Verify the Metric exists: Run curl http://<FE_LEADER_IP>:8030/metrics | grep txn_publish_schedule to ensure the FE is actually exporting it.
2. Update your Dashboard: Download the latest v4.0 JSON templates from the StarRocks GitHub.
3. Manual Query: If you don't want to re-import the whole dashboard, you can create a custom Grafana panel using this PromQL:
promql
# 99th percentile of publish scheduling delay
histogram_quantile(0.99, sum(rate(starrocks_fe_txn_publish_schedule_latency_ms_bucket{is_leader="true"}[5m])) by (le, type))
Summary of Dashboard Sections
Dashboard | Category/Row | Panel Goal
Shared-data | Publish Version | Monitor the latency and queue of shared-data metadata commits.
FE | Transaction | Monitor the end-to-end performance of loads (Stream, Routine, etc.).
References
• administration/management/monitoring/metrics.md
• administration/management/FE_configuration.md
• release_notes/release-4.0.md
• administration/management/monitoring/monitor_and_alert.md
References
• administration/management/monitoring/metrics.md
• administration/management/FE_configuration.mdGregM
06/10/2026, 1:02 PMPublish Version section of the shared-data general dashboard, I see Publish Tablet Version Latency / QPS and Queued Publish Tablet Tasks are these the right metrics for this issue?Rocky
06/10/2026, 1:03 PMpublish_version_queue_count
* What it tells you: This is the size of the FE's internal thread pool queue for publish tasks.
* Why it matters for your fix: If this number is consistently high (greater than 0), it means the FE cannot keep up with the volume of incoming transaction commits. When you set lake_enable_batch_publish_version = false, you are intentionally making each publish task "smaller" (one transaction at a time) but "more frequent." This can cause this queue to grow. If this queue hits its limit, you will see publish version timeout errors.
*2. Publish Tablet Version Latency / QPS*
* Source Metric: starrocks_fe_txn_publish_latency_ms (usually)
* What it tells you: The "Latency" shows how long it takes for a transaction to go from "Committed" to "Visible." The "QPS" shows how many transactions are being finished per second.
* Why it matters for your fix:
* Latency: After disabling batching, keep an eye on the 99th percentile (P99) here. If latency spikes significantly (e.g., above 1-2 seconds), your "delvec inconsistent" error might stop, but your users might notice a "data lag" where rows they just loaded don't appear in queries immediately.
* QPS: This should ideally match your ingestion rate (number of Stream Load or Routine Load jobs per second).
Are they the "Right" ones?
They are the "System Health" metrics, but they aren't the "Diagnostic" metrics.
* The metrics you found tell you if the system is slow.
* starrocks_fe_txn_publish_schedule_latency_ms (the one you were looking for) tells you why it is slow—specifically if the delay is happening in the scheduling logic (which is where the batching code lives) versus the execution (writing to the object store).
Recommendation
If you see Queued Publish Tablet Tasks rising after you set lake_enable_batch_publish_version to false, it means your FE is working harder to process transactions one-by-one. If it stays under control and your "delvec" errors stop, you have successfully stabilized the cluster.
Summary: Yes, watch these two panels. If Queued Tasks stays near zero and Latency stays under 500ms-1s, your change to false is perfectly safe for your current load.
References
• administration/management/monitoring/metrics.md
• administration/management/FE_configuration.md
• knowledge/usage/load/shared_data_batch_ingestion.md
• best_practices/primarykey_table.md
References
• administration/management/monitoring/metrics.mdGregM
06/10/2026, 2:19 PMFail to publish partition 2799768 error Fail to publish version for tablets:[[2799774, 2799771]], error msg: prepare_primary_index: load primary index failed: Already exist: PersistentIndexMemtable<51> insert found duplicate key <KEY> old_val 498216518911 old_ver 28 new_val 498216518912
be/src/storage/lake/lake_persistent_index.cpp:308 _memtable->insert(n, keys, values, version)
be/src/storage/lake/lake_persistent_index.cpp:840 insert(pkc->size(), reinterpret_cast<const Slice*>(pkc->raw_data()), values.data(), rowset_version), host: kube-starrocks-cn-2.kube-starrocks-cn-search.kube-starrocks.svc.cluster.local
Rocky
06/10/2026, 2:20 PMdelvec inconsistency is tied to a failure in the Primary Key Persistent Index during the publish phase.
What this error means
Already exist: PersistentIndexMemtable<51> insert found duplicate key <KEY>
In StarRocks Shared-data mode, when you load data into a Primary Key table, the system must update an index to know which row versions are current.
* The Conflict: The "PersistentIndexMemtable" is the memory-resident part of that index. This error means the system tried to "publish" a new version of a key, but it found that the key already existed in the index with a conflicting internal state.
* The Versioning: You see old_ver 28 and new_val .... This usually implies a retry or a race condition. The FE thought version 28 was ready to be published, but the CN node (where the index lives) already had a record of a change for that key that didn't match the FE's instruction.
Is this the "right" issue for the metrics?
Yes. This error directly causes the metrics you found in the dashboard to look "bad":
1. Fail to publish version: This error causes the task to fail.
2. Queued Publish Tablet Tasks: Because the task failed, the FE will retry it. If many tablets hit this error, the retry queue fills up.
3. Publish Latency: As long as this "duplicate key" conflict exists, the transaction cannot finish, causing latency to skyrocket to minutes or hours (until the transaction eventually times out or is manually fixed).
How to fix it
Since you are seeing this specifically in lake_persistent_index.cpp, here is the recommended path:
1. Immediate Workaround (The one you are currently trying)
Set lake_enable_batch_publish_version = false.
* Why? Batching combines multiple transactions into one "publish" task. If Transaction A and Transaction B both modify the same Primary Key, batching them together can sometimes trigger this internal conflict if they aren't handled atomically by the index. Disabling batching forces them to be processed one-by-one, which is much safer and usually stops this error.
2. If the error persists for a specific tablet
If a specific tablet ID (like 2799774) is "stuck" and keeps throwing this error even after disabling batching, the index for that tablet may be corrupted on the local disk of the CN.
* Action: You can try to clear the local persistent index cache for that tablet to force it to rebuild from the object store.
_ _Note: In shared-data mode, the "source of truth" is the object store, so deleting the local index file is safe; it will be redownloaded/rebuilt.*
Summary
The PersistentIndexMemtable error is the "smoking gun." The Grafana metrics (Queued Tasks and Latency) are showing you the symptoms, but this log entry explains the disease. Setting lake_enable_batch_publish_version = false is the correct first step to stabilize this.
References
• table_design/table_types/primary_key_table.md
• administration/management/monitoring/metrics.md
• administration/management/FE_configuration.md
References
• faq/loading/Loading_faq.md
• administration/management/monitoring/metrics.md
• best_practices/primarykey_table.md
• table_design/table_types/duplicate_key_table.md
• table_design/table_types/primary_key_table.mdGregM
06/10/2026, 2:34 PMRocky
06/10/2026, 2:34 PMlake_enable_batch_publish_version is a mutable configuration, meaning it can be updated dynamically while the cluster is running.
How to apply it
Run the following SQL command as an admin user (e.g., root):
sql
ADMIN SET FRONTEND CONFIG ("lake_enable_batch_publish_version" = "false");
Important Notes:
1. Persistence: While the ADMIN SET FRONTEND CONFIG command takes effect immediately, it will be lost if the FE service restarts. To make the change permanent, you should also add/update this line in your fe.conf file on every FE node:
properties
lake_enable_batch_publish_version = false
2. Verification: You can verify that the setting has been applied by running:
sql
ADMIN SHOW FRONTEND CONFIG LIKE 'lake_enable_batch_publish_version';
3. Scope: This setting is handled by the FE Leader. Once you run the command, the Leader will stop batching publish tasks for shared-data tables immediately.
References
• administration/management/FE_configuration.md
• knowledge/usage/load/shared_data_batch_ingestion.md
References
• administration/management/FE_configuration.md
• knowledge/usage/load/shared_data_batch_ingestion.md
References
• administration/management/FE_configuration.md
• knowledge/usage/load/shared_data_batch_ingestion.mdGregM
06/10/2026, 2:46 PMRocky
06/10/2026, 2:46 PMlake_enable_batch_publish_version was set to true. This fix makes the batching mechanism much safer for Primary Key tables.
2. Fix for Shared-Data Transaction Log Races (#72237, #71992)
There were races in the "combined transaction log" mode where legitimate logs were incorrectly classified as "orphans" and dropped.
* Relevance: When logs are dropped or misclassified, the FE and the CN nodes (BEs) get out of sync regarding which versions of a key exist. This leads to the Already exist: PersistentIndexMemtable insert found duplicate key error you encountered, as the CN tries to insert a key version it mistakenly thinks is new or already handled.
3. Performance: Intra-Tablet Parallelism (New in 4.1)
StarRocks 4.1 introduces Phase 1 of Large-Capacity Tablet Support, which includes parallelizing the Primary Key update and compaction pipeline within a single tablet.
* Relevance: In 4.0.9, a single large tablet could become a bottleneck during the publish phase because updates were largely single-threaded per tablet. 4.1 allows the CN to process these updates in parallel, which should significantly reduce the Publish Tablet Version Latency you are monitoring in Grafana.
4. Stability fix for v4.1.1 specifically (#71825)
If you are considering the 4.1 branch, v4.1.1 is a required upgrade over v4.1.0.
* Warning: v4.1.0 had an unstable load order issue in container environments that could cause BE processes to fail to start reliably. This is fixed in 4.1.1.
Summary Comparison
Feature / Fix | v4.0.9 | v4.1.1
Delvec Batching Fix | ❌ Affected by #71049 | ✅ Fixed
Txn Log Race Fix | ❌ Affected by #72237 | ✅ Fixed
PK Parallelism | ❌ Single-threaded per tablet | ✅ Intra-tablet parallel updates
Tablet Support | Standard limits | ✅ Optimized for 100GB+ tablets
Recommendation:
If you are currently on 4.0.9 and experiencing these errors, upgrading to 4.1.1 is highly recommended. It should allow you to re-enable lake_enable_batch_publish_version = true safely, which will lower your FE CPU overhead while the code fixes prevent the metadata inconsistencies you've been battling.
References
• knowledge/usage/load/shared_data_batch_ingestion.md
• best_practices/primarykey_table.md
• administration/management/monitoring/metrics.md
• table_design/table_types/primary_key_table.md
• administration/management/FE_configuration.md
• faq/loading/Loading_faq.mdGregM
06/10/2026, 2:49 PMRocky
06/10/2026, 2:49 PMvalues.yaml is the primary step, there are a few critical safety precautions you should take for a minor version jump (4.0 to 4.1) in Shared Data mode to ensure metadata consistency.
1. The Correct Order (CN then FE)
In StarRocks, BEs and CNs are backward compatible with FEs. For a rolling upgrade to work without downtime:
* Update CNs first: Change the image tag for the CNs in your Helm values and run helm upgrade. Wait for all CN pods to be Running and Healthy.
* Update FEs second: After the CNs are done, update the FE image tag and run helm upgrade.
2. Mandatory Pre-Upgrade Steps
Before you trigger the upgrade, run these SQL commands as an admin. These prevent the cluster from trying to move data around (balancing) while pods are restarting, which can lead to "tablet not found" errors during the transition.
sql
-- 1. Disable balancing and scheduling
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_scheduling_tablets" = "0");
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "0");
ADMIN SET FRONTEND CONFIG ("disable_balance" = "true");
ADMIN SET FRONTEND CONFIG ("disable_colocate_balance" = "true");
-- 2. Create a fresh metadata image (Safety backup)
-- This ensures that if the FE fails to upgrade, you have a clean starting point.
ALTER SYSTEM CREATE IMAGE;
Note: Check fe.log to ensure the image creation finishes before starting the Helm upgrade.
3. Shared Data Specifics for 4.1
StarRocks 4.1 introduces Large-Capacity Tablet Support and internal changes to how the Persistent Index is stored (adding remote-storage mapper files).
* Automatic Migration: These changes happen automatically as data is written/compacted in 4.1. You don't need to run manual migration scripts.
* Downgrade limit: If you need to roll back, you can downgrade from 4.1 back to 4.0.9. However, the docs note that you cannot downgrade to any version below 4.0.6 due to metadata layout changes introduced in 4.1.
4. Helm Checklist
1. Avoid 4.1.0: Use 4.1.1 (or later). 4.1.0 has a known race condition in container environments where BE/CN processes fail to start.
2. Resources: 4.1's new features (like parallel compaction) may slightly increase CPU usage during heavy loads. Ensure your CN resource limits have a small buffer.
3. Persistence: Ensure your lake_enable_batch_publish_version = false setting is added to the fe.conf section of your Helm values so it isn't wiped out by the upgrade.
Summary of Workflow
1. SQL: Disable balancing + ALTER SYSTEM CREATE IMAGE.
2. Helm: Update values.yaml with 4.1.1 image tags for CN.
3. Command: helm upgrade <release> starrocks/kube-starrocks -f values.yaml.
4. Wait: Ensure all CNs are healthy.
5. Helm: Update values.yaml for FE image tags.
6. Command: helm upgrade ...
7. SQL: Re-enable balancing (set the 4 configs from step 2 back to their defaults).
References
• deployment/upgrade.md
• releasenotes/release-4.1.md
• administration/management/FE_configuration.md
References
• deployment/upgrade.md
• quick_start/helm.mdGregM
06/10/2026, 2:51 PMlake_enable_batch_publish_version = false as true because the upgrade will work better with it?Rocky
06/10/2026, 2:52 PMfalse during the actual upgrade process, and only switch it back to true after the cluster is fully running on version 4.1.1.
Here is why and how you should handle this specific flag:
1. Why keep it false during the upgrade?
While StarRocks 4.1.1 fixes the "delvec inconsistency" bug, the upgrade involves a period where your cluster is in a mixed state (some nodes on 4.0.9 and some on 4.1.1).
* The batch publish logic requires coordination between the FE and the CNs.
* Running a "batch publish" from a 4.1.1 FE to a 4.0.9 CN (or vice versa) during the rolling restart could trigger the very race conditions and inconsistency issues you are trying to avoid.
* Keeping it false ensures that every transaction is published individually and conservatively while the cluster is unstable.
2. When to switch it to true?
Once your Helm deployment is finished and all FE and CN pods are healthy on version 4.1.1, you should re-enable it. This is where you get the performance benefits (lower FE CPU and higher ingestion throughput) without the risk of data inconsistency.
Updated Workflow Recommendation:
1. Before Upgrade: Keep lake_enable_batch_publish_version = false in your fe.conf (via Helm config or extraArgs).
2. Perform Upgrade: Deploy 4.1.1 (CNs first, then FEs).
3. Post-Upgrade Verification: Run a few smoke tests/loads to ensure the Already exist errors have stopped.
4. Re-enable Optimization: Switch the flag to true dynamically to restore performance:
sql
ADMIN SET FRONTEND CONFIG ("lake_enable_batch_publish_version" = "true");
5. Finalize: Update your Helm values.yaml to set it to true so the setting persists across future pod restarts.
Summary
* 4.0.9: Must be false (Buggy).
* During Upgrade: Keep false (Safety).
* 4.1.1 (Complete): Set to true (Fixed & Recommended).
If I previously implied it should be true during the upgrade, I misspoke—stability is priority #1 while the binaries are being swapped.
References
• releasenotes/release-4.1.md
• administration/management/FE_configuration.md
• deployment/upgrade.md
• knowledge/usage/load/shared_data_batch_ingestion.md
References
• deployment/upgrade.md
• release_notes/release-4.0.md
• administration/management/FE_configuration.mdGregM
06/10/2026, 2:55 PMRocky
06/10/2026, 2:55 PMAlready exist: PersistentIndexMemtable insert found duplicate key error in shared-data mode is almost always caused by the FE and CN nodes losing track of which transaction logs actually "made it" into the storage layer.
* The Bug: In 4.0.9, there were race conditions in "combined transaction log" mode where valid logs were incorrectly flagged as "orphans" and discarded.
* The Result: The FE thinks a version was written, but the CN never "saw" it. When the next write comes in, the CN tries to index a key that its local Persistent Index says already exists (but the metadata log says is new).
* The Fix: 4.1.1 (and 4.0.10) includes specific fixes to the transaction log dispatch logic to ensure these logs are never dropped.
2. Resolution for Delvec Inconsistency (#71049)
If you were seeing delvec inconsistency after setting lake_enable_batch_publish_version = true, 4.1.1 contains the fix for a known issue where compaction and batch-publish would collide. This allows you to safely re-enable the batching optimization in 4.1.1, which will significantly drop your FE CPU usage.
3. Relief for "Publish Tablet Version Latency"
A major feature of 4.1 is Intra-tablet Parallelism.
* In 4.0.9, publishing a new version to a Primary Key tablet is largely a single-threaded operation per tablet. If you have large tablets or high ingestion rates, the "Publish" phase (visible in your Grafana) becomes a bottleneck.
* In 4.1, StarRocks can parallelize the primary key update and compaction pipeline inside a single tablet. This should drastically reduce those "Publish Latency" spikes you are seeing.
4. Safety of 4.1.1 vs 4.1.0
It is important that you go to 4.1.1 and not 4.1.0. The 4.1.0 container image had an unstable load order bug (#71825) that caused CN/BE pods to randomly fail to start in Kubernetes. 4.1.1 was released specifically to fix that.
Summary:
I am confident that 4.1.1 will stop the metadata/index corruption you are fighting. The "Duplicate Key" error is explicitly addressed by the txn-log race fixes in this branch.
Final Upgrade Tip:
When you perform the upgrade via Helm, ensure you monitor the starrocks_be_staros_shard_info_fallback_total metric in Grafana once you're on 4.1.1. This will help you verify that the new metadata handling is working smoothly without excessive remote lookups.
References
• releasenotes/release-4.1.md
• administration/management/FE_configuration.md
• table_design/table_types/primary_key_table.md
• deployment/helm.md
• administration/management/monitoring/metrics.mdGregM
06/10/2026, 3:24 PMRocky
06/10/2026, 3:25 PMlake_enable_batch_publish_version = true once you are fully on 4.1.1, which significantly reduces FE CPU load.
* Persistent Index Memory Leaks: Several fixes for memory bloat in the Persistent Index during high-frequency updates on CN nodes.
2. High-Scale Shared-Data Features (Primary Key Optimizations)
* Large-Capacity Tablet Support (Phase 1): Shared-data tablets can now scale toward 100 GB per tablet (up from the previous ~10 GB recommendation).
* Intra-Tablet Parallelism: This is the biggest performance boost. In 4.0.9, a single tablet was a single-threaded bottleneck for ingestion and compaction. 4.1 introduces:
* Parallel Compaction: Compaction can now split a single large tablet into segments and process them in parallel.
* Parallel Publish: Drastically reduces the "latency" during the transaction commit phase (the "Publish" step in your logs).
* Remote-Storage Persistent Index Mapper: The Persistent Index now uses remote-storage mapper files. This makes index recovery much faster after a CN pod restarts or a shard rebalance.
3. Management & Usability Improvements
* Range-Based Data Distribution: Supports automatic splitting and merging of tablets. If a specific range of data (e.g., a "hot" day) grows too large, StarRocks can split it automatically to distribute the load across more CNs without you needing to re-bucket the table.
* Fast Schema Evolution V2: Second-level DDL for shared-data tables (adding/dropping columns). This is now extended to work with Materialized Views as well.
* Inverted Index Support (Beta): You can now use Inverted Indexes in Shared-Data mode to accelerate full-text searches and WHERE clauses on non-sort-key columns.
4. Operational & Observability Gains
* Container Startup Fix (#71825): 4.1.1 specifically fixes a race condition in the 4.1.0 container image that caused BE/CN processes to fail to start in Kubernetes.
* Cache Transparency: New metrics for Cache Hit Ratio and Disk/Memory Quota usage are now exposed in audit logs and Prometheus. This helps you determine if your CN local disks are undersized.
* Iceberg Improvements: Shared-data clusters now support DELETE operations on Iceberg tables and better metadata synchronization.
Important: The "No-Return" Window
While you can downgrade from 4.1.1 to 4.0.9 if needed, do not downgrade to any version below 4.0.6. 4.1 introduces metadata layout changes that versions earlier than 4.0.6 do not understand and could cause metadata corruption if a downgrade is attempted.
Summary Recommendation:
Upgrading to 4.1.1 is highly recommended for your use case. It specifically targets the Primary Key "bottleneck" and "metadata inconsistency" issues that are common on the 4.0.9 branch.
References
• release_notes/release-3.5.md
• release_notes/release-3.4.md
• release_notes/release-3.3.mdGregM
06/10/2026, 5:27 PMRocky
06/10/2026, 5:28 PMAlready exist and metadata-related errors on version 4.0.9. If you leave pipes running during a rolling upgrade:
* Transactions will likely fail as CN and FE pods restart.
* Retries triggered by the pipe might overlap with the version change, potentially triggering more of the very index/metadata inconsistencies you are trying to fix.
* By pausing, you ensure that the metadata state is "frozen" while you swap the binaries.
2. Avoiding "Mixed Version" Logic Errors
The Pipe feature relies on coordination between the FE (which tracks file state) and the CN (which performs the load). During the upgrade, you will have a period where a 4.1.1 FE might be talking to a 4.0.9 CN. Since 4.1.1 introduces significant changes to how shared-data transactions are handled, it is safer not to have active ingestion tasks crossing that version boundary.
3. Clean Recovery
If a pipe fails during a node restart, it usually retries automatically. However, in a shared-data environment, if a transaction is "stuck" in a middle state because of an upgrade restart, it's much cleaner to resume from a known paused state than to troubleshoot a failed/partial transaction log created during a version jump.
──────────
Recommended Workflow:
1. Suspend all active pipes:
sql
-- Do this for each active pipe
ALTER PIPE <pipe_name> SUSPEND;
Verify they are suspended via SHOW PIPES;.
2. Perform the Upgrade:
* Upgrade CNs (one by one or via Helm rolling update).
* Upgrade Follower FEs.
* Upgrade Leader FE.
3. Verify Cluster Health:
* Check that all nodes are Alive and running 4.1.1.
* Ensure your lake_enable_batch_publish_version flag is set correctly (start with false and move to true once stable).
4. Resume Pipes:
Resume them one at a time to monitor for any errors:
sql
ALTER PIPE <pipe_name> RESUME;
Pro-Tip:
If you have a large number of pipes, you can generate the suspend/resume commands using the `information_schema`:
sql
-- Generate Suspend commands
SELECT CONCAT('ALTER PIPE ', database_name, '.', pipe_name, ' SUSPEND;')
FROM information_schema.pipes WHERE state = 'RUNNING';
References
• sql-reference/sql-statements/loading_unloading/pipe/SUSPEND_or_RESUME_PIPE.md
• deployment/upgrade.md
• loading/hdfs_load.md
• loading/s3.md
References
• deployment/upgrade.md
• release_notes/release-3.2.md
• loading/hdfs_load.mdGregM
06/10/2026, 6:18 PM"5064 (42000): Getting analyzing error. Detail message: Class 'udfs.LatLonToH3UDF' not found in object_file :file:///opt/starrocks/udf-jars/starrocks-geo-udf-all-1.1.jar,udfs.LatLonToH3UDF.",
did something change with how udfs are loadedRocky
06/10/2026, 6:18 PMCREATE FUNCTION statement is likely missing or inaccessible on the new 4.1.1 pods.
In a Kubernetes or shared-data environment, using file:/// for UDFs is risky because when you upgrade (which replaces the pods), the local filesystem of the new pods is fresh and won't contain the JAR file unless you explicitly mounted it via a Persistent Volume or hostPath.
1. The Immediate Cause: Missing JAR or Permissions
The error Class '...' not found in object_file often occurs when StarRocks fails to correctly open or read the JAR at the specified path on the BE/CN nodes.
* Check existence: Exec into one of your new CN/BE pods and verify if /opt/starrocks/udf-jars/starrocks-geo-udf-all-1.1.jar actually exists.
* Permissions: Ensure the starrocks user inside the container has read access to that file.
2. The "Correct" Fix for Shared-Data/K8s
The recommended way to handle UDFs in a distributed, cloud-native environment is to host the JAR on an HTTP/HTTPS server (or S3/Minio). This ensures that whenever a new CN pod scales up or restarts, it can automatically download the JAR.
Recommendation:
1. Upload the JAR to an internal S3 bucket or a simple HTTP server accessible by the cluster.
2. Drop and recreate the function using the HTTP URL:
sql
DROP FUNCTION LatLonToH3UDF(...); -- matching your signature
CREATE FUNCTION LatLonToH3UDF(DOUBLE, DOUBLE, INT)
RETURNS STRING
PROPERTIES (
"symbol" = "udfs.LatLonToH3UDF",
"type" = "StarrocksJar",
"file" = "<http://your-internal-server/starrocks-geo-udf-all-1.1.jar>"
);
3. Check for JDK 17 Requirements
StarRocks 4.x (built on the 3.x line) requires JDK 17 for Java UDFs. If your UDF was compiled with an older version or if the new BE images are missing specific JVM flags, it may fail to load.
Ensure your be.conf (or the BE environment variables in Helm) includes these flags in JAVA_OPTS to allow the UDF classloader to work:
bash
--add-opens=java.base/java.nio=ALL-UNNAMED
--add-opens=java.base/sun.nio.ch=ALL-UNNAMED
4. Why did it work before?
If you weren't using a Persistent Volume, you might have manually copied the JAR into the 4.0.9 pods. When you upgraded to 4.1.1, the Helm chart deleted the old pods and created new ones, wiping out any files you manually placed in /opt/starrocks/.
Next Steps:
* Verify the JAR exists on the pod.
* If you must use local files, you'll need to update your Helm values.yaml to mount a volume containing the JARs.
* Otherwise, switching the file property to an HTTP URL is the most stable fix for 4.1.1.
References
• sql-reference/sql-functions/JAVA_UDF.md
• administration/management/FE_configuration.md
• release_notes/release-3.5.md
• deployment/helm.md
• sql-reference/sql-statements/loading_unloading/pipe/CREATE_PIPE.md
References
• sql-reference/sql-functions/hive_bitmap_udf.md
• sql-reference/sql-functions/Python_UDF.md
• sql-reference/sql-functions/JAVA_UDF.md
• release_notes/release-4.0.md
• release_notes/release-3.5.md
• release_notes/release-2.2.md
• release_notes/release-3.4.mdGregM
06/10/2026, 6:21 PMbash
--add-opens=java.base/java.nio=ALL-UNNAMED
--add-opens=java.base/sun.nio.ch=ALL-UNNAMEDRocky
06/10/2026, 6:21 PMadd-opens flags, the JVM will block the StarRocks C++ process (via JNI) from accessing the internal Java memory buffers required to pass data between the database and your UDF.
Why this is required for CNs:
* Role Identity: In Shared-Data clusters, CNs perform the exact same computation role that BEs do in Shared-Nothing clusters. Any requirement for "BE configuration" regarding execution or UDFs applies directly to CNs.
* Data Passing: StarRocks uses specific Java internal APIs (java.nio) to move data efficiently between the C++ engine and the Java VM. JDK 17 "strongly encapsulates" these APIs by default.
How to add them to CNs:
If you are running in Kubernetes (Helm), you should add these to the envVars or config section of your CN spec in the `values.yaml`:
yaml
compute:
envVars:
- name: JAVA_OPTS
value: "-Xmx8G --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
If you are running manually (on VMs), add them to your cn/conf/cn.conf (which is often just a renamed be.conf):
bash
# Add to the existing JAVA_OPTS line
JAVA_OPTS="... --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
Summary of required flags for 4.1.x:
1. For Java UDFs:
* --add-opens=java.base/java.nio=ALL-UNNAMED
* --add-opens=java.base/sun.nio.ch=ALL-UNNAMED
2. For External Catalogs (e.g., Iceberg/Hive):
* --add-opens=java.base/java.util=ALL-UNNAMED (Also highly recommended to avoid InaccessibleObjectException).
Note: After adding these flags, you must restart the CN processes for the changes to take effect.
References
• sql-reference/sql-functions/JAVA_UDF.md
• administration/management/FE_configuration.md
• release_notes/release-3.5.md
• deployment/helm.md
• sql-reference/sql-statements/loading_unloading/pipe/CREATE_PIPE.md
References
• sql-reference/sql-functions/JAVA_UDF.mdGregM
06/10/2026, 6:22 PMRocky
06/10/2026, 6:22 PM/opt/starrocks/udf-jars/ directory of the running pods manually or via a startup script that wasn't persisted.
* The Upgrade: When you upgraded to 4.1.1, the Helm chart (or operator) deleted the old 4.0.9 pods and created brand new 4.1.1 pods.
* The Result: Since the local filesystem of a pod is ephemeral, the /opt/starrocks/udf-jars/ folder in the new pods is empty. Because the CREATE FUNCTION statement points to a local file path (file:///...), the CN nodes are looking for a file that no longer exists on their new disks.
2. JDK 17 & JNI Strictness
StarRocks 4.x (and the 3.5+ line it is based on) requires JDK 17.
* Version 4.1.x introduced more rigorous error checking for Java JNI calls. In older versions, if the JVM had a minor initialization issue or a "soft" failure due to missing JAVA_OPTS, the engine might have silently retried or bypassed the check in a way that appeared to work.
* Version 4.1.1 now explicitly checks for exceptions during JNI object creation. If your JAVA_OPTS (the --add-opens flags) are missing, the JVM throws an InaccessibleObjectException. In 4.1.1, this now correctly bubbles up as an "Analyzing error" or "Class not found" because the classloader failed to initialize the environment properly.
3. Changes in UDF Loading Logic
Release notes for the 4.1.x line (specifically around 4.1.1 and 4.0.10) indicate that Java UDF/UDAF instances are now loaded once per query and reused across pipeline instances to improve performance.
* In 4.0.9, the loading happened more frequently/differently.
* In 4.1.1, the new centralized loading logic is more sensitive to environment issues. If the JAR isn't exactly where it's expected or if the JVM permissions are missing, the query will fail immediately during the "Analyzing" phase before the actual execution starts.
──────────
How to verify and fix:
1. Confirm the file is missing:
kubectl exec -it <cn-pod-name> -- ls -l /opt/starrocks/udf-jars/
If it’s empty, you've found the issue.
2. The Permanent Fix: Move the JAR to a remote location (S3, Minio, or an HTTP server) and update the function to use an http:// or s3:// URL. This makes the UDF "pod-restart proof."
3. Add the Flags: Ensure those --add-opens flags are in your CN environment variables. Even if you get the file back, the UDF will likely crash or return errors without them on JDK 17.
References
• sql-reference/sql-functions/JAVA_UDF.md
• release_notes/release-4.1.md
• administration/management/FE_configuration.md
• release_notes/release-3.5.md
• deployment/helm.md
References
• sql-reference/sql-functions/JAVA_UDF.md
• release_notes/release-4.1.md
• release_notes/release-3.5.md
• release_notes/release-4.0.md
• administration/management/FE_configuration.md
References
• sql-reference/sql-functions/JAVA_UDF.mdRocky
06/10/2026, 6:22 PMGregM
06/10/2026, 6:24 PMRocky
06/10/2026, 6:24 PMJAVA_OPTS to your FE (Front End) as well.
While the BE/CN does the heavy lifting for UDF execution, the FE is responsible for the Analysis phase. During this phase, the FE attempts to load the JAR metadata to verify that the symbol (your class name) and the function signature are valid.
If the FE is running on JDK 17 without these flags, it can encounter the same "strong encapsulation" errors when trying to inspect the JAR or initialize the classloader, leading to the "Analyzing error" you are seeing.
1. Update fe.conf
Add these to your JAVA_OPTS in `fe.conf`:
bash
JAVA_OPTS="-Xmx8192m --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
(Note: If you are using External Catalogs like Iceberg or Hive, you should also add --add-opens=java.base/java.util=ALL-UNNAMED to the FE).
2. The "Analyzing Error" and file:///
The specific error Class ... not found in object_file :file:///... usually points to one of two issues on the FE side:
* Locality: When you use file:///, the JAR file must exist on the FE pod at that exact path. If you only put the JAR on the CN/BE pods, the FE will fail during the analysis/planning stage because it can't find the file to validate your UDF.
* Permissions: The FE process must have read permissions for that directory and file.
Recommendation: Switch to HTTP
To avoid having to manually sync the JAR file across every single FE, CN, and BE pod (and ensuring it survives pod restarts), you should host the JAR on an internal HTTP/S3 server.
When you use an HTTP URL, the FE and CNs will automatically download the JAR into their local cache when needed, making the cluster much easier to manage.
sql
-- Recreate using a URL instead of a local path
CREATE FUNCTION LatLonToH3UDF(...)
RETURNS STRING
PROPERTIES (
"symbol" = "udfs.LatLonToH3UDF",
"type" = "StarrocksJar",
"file" = "<http://your-internal-repo/starrocks-geo-udf-all-1.1.jar>"
);
Summary of Actions
1. Add the add-opens flags to FE JAVA_OPTS to ensure the JVM can handle the UDF metadata analysis.
2. Verify the JAR exists on the FE pod if you continue using file:///.
3. Restart the FE after modifying fe.conf.
References
• sql-reference/sql-functions/JAVA_UDF.md
• administration/management/FE_configuration.md
• release_notes/release-3.5.md
• deployment/helm.md
References
• sql-reference/sql-functions/JAVA_UDF.md
• administration/management/FE_configuration.md
• release_notes/release-3.5.md
References
• sql-reference/sql-functions/JAVA_UDF.md
• administration/management/FE_configuration.md
• administration/management/BE_configuration.mdGregM
06/10/2026, 6:26 PMRocky
06/10/2026, 6:27 PMJAVA_OPTS is a static JVM configuration, it cannot be updated dynamically via SQL. You must modify the configuration files and restart the processes.
To maintain cluster availability, you should follow a rolling restart process.
Scenario A: Manual Deployment (On VMs)
If you are managing the processes directly on Linux servers:
1. Update the Configuration Files
On every FE and CN node, locate the configuration files and append the required flags to the JAVA_OPTS line.
* FE: fe/conf/fe.conf
* CN: cn/conf/cn.conf (or be.conf if that is what you are using)
bash
# Example line in fe.conf/cn.conf
JAVA_OPTS="-Xmx... --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
2. Rolling Restart Sequence
Restart nodes one by one to ensure the cluster remains online.
For CN Nodes:
1. Stop Gracefully: Run ./bin/stop_cn.sh --graceful (or -g). This allows the CN to finish in-flight queries before shutting down.
2. Start: Run ./bin/start_cn.sh --daemon.
3. Verify: Check the logs or run SHOW COMPUTE NODES; to ensure it is Alive.
4. Repeat for the next CN.
For FE Nodes:
1. Start with Followers: Restart the non-leader FEs first.
2. Stop Gracefully: Run ./bin/stop_fe.sh -g.
3. Start: Run ./bin/start_fe.sh --daemon.
4. Restart Leader Last: When you stop the Leader FE, a new Leader will be elected. The cluster will have a few seconds of "write-unavailability" during the election, but reads will continue.
──────────
Scenario B: Kubernetes Deployment (Helm/Operator)
If you are using the StarRocks Kubernetes Operator or Helm chart, the process is much simpler as Kubernetes handles the orchestration.
1. Update your values.yaml
Add the flags to the envVars section for both the FE and CN components.
yaml
fe:
envVars:
- name: JAVA_OPTS
value: "-Xmx8G --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
compute: # or 'cn' depending on your chart version
envVars:
- name: JAVA_OPTS
value: "-Xmx8G --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
2. Apply the Change
Run the Helm upgrade command:
bash
helm upgrade <release-name> starrocks/starrocks-stack -f values.yaml
3. Automatic Rolling Update
Kubernetes will detect the environment variable change and perform a Rolling Update:
* It will terminate one pod at a time.
* It will wait for the new pod to be Ready (Health Check pass) before moving to the next.
* Since your JAR files are "placed on the pods correctly," ensure your placement method (like an initContainer or a mounted HostPath) is still active so the new pods get the files upon startup.
How to verify the fix
After the restart, you can verify the JVM is running with the new flags by running this command inside the pod/server:
bash
ps aux | grep java
Look for the --add-opens flags in the process arguments. Once verified, your UDF should no longer throw the "Analyzing error" or "InaccessibleObjectException."
References
• administration/management/graceful_exit.md
• deployment/upgrade.md
• administration/management/FE_configuration.md
• deployment/helm.md
References
• administration/management/graceful_exit.md
• deployment/upgrade.md
• administration/management/FE_configuration.md
References
• administration/management/graceful_exit.mdRocky
06/10/2026, 6:27 PMGregM
06/10/2026, 6:28 PMJAVA_OPTS="-Dlog4j2.formatMsgNoLookups=true -Xms16g -Xmx16g -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -Xlog:gc*:${LOG_DIR}/fe.gc.log.$DATE:time"Rocky
06/10/2026, 6:29 PMJAVA_OPTS. You do not need to replace anything, as your current flags (G1GC, Metaspace, and log4j protection) are all still valid and recommended for StarRocks.
The Combined FE JAVA_OPTS
You can copy and paste this combined line into your `fe/conf/fe.conf`:
bash
JAVA_OPTS="-Dlog4j2.formatMsgNoLookups=true -Xms16g -Xmx16g -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -Xlog:gc*:${LOG_DIR}/fe.gc.log.$DATE:time --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED"
Why these three specifically?
1. java.nio & <http://sun.nio.ch|sun.nio.ch>: These are strictly required for Java UDFs. They allow the StarRocks engine to use direct memory buffers for passing data between the C++ engine and the JVM. Without these, you get the "InaccessibleObjectException" during the Analyzing phase.
2. java.util: While the docs primarily mention this for External Catalogs (Hive/Iceberg), it is highly recommended to include it on the FE for UDFs as well. Many Java libraries used inside UDFs (like H3, Jackson, or Guava) use reflection on java.util structures which JDK 17 blocks by default.
What about the CN?
For your CN (Compute Nodes), you should use a similar approach. Since CNs usually don't need as much Heap memory as the FE (because they use off-heap memory for processing), a common CN JAVA_OPTS looks like this:
bash
# Example for CN (adjust -Xmx based on your pod memory limit)
JAVA_OPTS="-Xms4g -Xmx4g --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED"
Verification Step
After you update the files and restart the pods, run this command to make sure the flags actually took effect:
bash
ps aux | grep java
If you see the --add-opens strings in the output of the running FE and CN processes, your UDFs should start working immediately.
References
• sql-reference/sql-functions/JAVA_UDF.md
• release_notes/release-3.5.md
• administration/management/FE_configuration.md
• faq/Others.md
References
• sql-reference/sql-functions/JAVA_UDF.md
• release_notes/release-3.5.md
• administration/management/FE_configuration.md
References
• sql-reference/sql-functions/JAVA_UDF.md
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
• faq/Others.md
• knowledge/trouble_shooting/fe_memory_problems.mdGregM
06/10/2026, 6:31 PMRocky
06/10/2026, 6:31 PM--add-opens bits, but there is a catch: StarRocks configuration usually treats JAVA_OPTS as an override.
If you define JAVA_OPTS in cn.conf, the startup script will likely use only what you provide and ignore its internal defaults. If those defaults included a memory limit (like -Xmx), you might unintentionally change how much memory the JVM uses.
Recommendation: Set a small Heap for CNs
Unlike the FE (which needs 16GB+), the CN doesn't use the JVM for its main engine; it only uses it for "helper" tasks like Java UDFs and reading certain external formats (Hudi/Iceberg).
Because you don't want to mess with memory too much, I recommend adding a safe, conservative heap size along with your required flags. This ensures the JVM has enough room to run your H3 UDF without competing with the main C++ process for all the system's RAM.
Add this to your cn.conf (or be.conf):
bash
JAVA_OPTS="-Xms1g -Xmx1g --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED"
Why -Xmx1g?
* Safety: 1GB is usually plenty for running UDFs.
* Predictability: CN nodes are designed to use most of their RAM for the C++ memory pool (tracked by mem_limit). By capping the JVM at 1GB, you ensure it doesn't grow unexpectedly and cause the pod to be OOM-killed (Out of Memory) by the OS or Kubernetes.
* Defaults: If you provide no memory flags, the JVM defaults to using 1/4 of the physical memory. On a 64GB machine, that’s 16GB—which is likely much more than you want the JVM to take away from the main StarRocks engine.
Summary
1. FE: Use your existing 16GB string + the three --add-opens flags.
2. CN: Add the line above (-Xmx1g + the three flags).
3. Restart: Perform the rolling restart as discussed.
References
• sql-reference/sql-functions/JAVA_UDF.md
• release_notes/release-3.5.md
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
References
• sql-reference/sql-functions/JAVA_UDF.md
• release_notes/release-3.5.md
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
References
• sql-reference/sql-functions/JAVA_UDF.md
• deployment/environment_configurations.md
• administration/management/FE_configuration.md
• administration/management/BE_configuration.md
• deployment/deploy_manually.md
• sql-reference/System_variable.mdGregM
06/10/2026, 6:36 PM"5064 (42000): Getting analyzing error. Detail message: Class 'udfs.LatLonToH3UDF' not found in object_file :file:///opt/starrocks/udf-jars/starrocks-geo-udf-all-1.1.jar,udfs.LatLonToH3UDF.",Rocky
06/10/2026, 6:38 PMGregM
06/10/2026, 6:49 PM"file" = "file:///..." method of registering UDFs in 4.1.1 or was that depreciated?Rocky
06/10/2026, 6:49 PMfile:/// method is not officially deprecated, but it is strongly discouraged in distributed environments, and the behavior you are seeing is exactly why.
In StarRocks (including version 3.x and 4.x), the recommended way to register a UDF is via an HTTP/HTTPS URL.
Why file:/// is likely causing your error
When you use file:///, StarRocks expects that every single FE and every single CN/BE node has that exact JAR file at that exact same local path (/opt/starrocks/udf-jars/...).
The error "Class 'udfs.LatLonToH3UDF' not found in object_file..." typically happens for one of two reasons:
1. Missing File on Worker Nodes: The CN node executing the query doesn't have the JAR file at that path.
2. Symbol Mismatch: The JAR exists, but the class name provided in the symbol property doesn't match the actual package/class structure inside the JAR.
The Recommended Fix: Use an HTTP Server
Instead of trying to sync files across all your pods manually, the standard approach is to host the JAR on a simple HTTP server (like an internal Nginx, an S3 bucket with a public/presigned URL, or even a simple Python http.server running in a management pod).
Update your registration to this format:
sql
CREATE [GLOBAL] FUNCTION h3_lat_lon_to_cell(DOUBLE, DOUBLE, INT)
RETURNS BIGINT
PROPERTIES (
"symbol" = "udfs.LatLonToH3UDF",
"type" = "StarrocksJar",
"file" = "<http://your-internal-repo/starrocks-geo-udf-all-1.1.jar>"
);
If you must use file:///
If you are determined to use the local path (e.g., you are using a Shared Volume in Kubernetes like an NFS/PVC mounted to all pods):
1. Verify the Class Name: Run this command to ensure the class udfs.LatLonToH3UDF is actually inside the JAR:
bash
jar -tf /opt/starrocks/udf-jars/starrocks-geo-udf-all-1.1.jar | grep LatLonToH3UDF
The output should look like udfs/LatLonToH3UDF.class. If it looks like com/example/udfs/LatLonToH3UDF.class, your symbol must be com.example.udfs.LatLonToH3UDF.
2. Check Permissions: Ensure the starrocks user in your container has read permissions for both the directory and the JAR file.
3. Check all CNs: Log into every CN pod and verify the file exists. If even one pod is missing it, the query will fail whenever it happens to be scheduled on that node.
Pro-tip: Since you are on a very recent version (4.x), using an HTTP URL is much safer because StarRocks will automatically download the JAR and cache it locally on each node, ensuring consistency across the cluster, ensuring consistency.
References
• sql-reference/sql-functions/JAVA_UDF.md
• sql-reference/sql-statements/Function/CREATE_FUNCTION.md
• release_notes/release-4.0.md
References
• sql-reference/sql-functions/JAVA_UDF.md
• sql-reference/sql-statements/Function/CREATE_FUNCTION.md
• release_notes/release-4.0.md
• release_notes/release-2.1.md
-index)
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
• deployment/environment_configurations.md
• deployment/deploy_manually.md
• sql-reference/System_variable.mdRocky
06/10/2026, 6:49 PMGregM
06/10/2026, 6:53 PMstarrocks@kube-starrocks-cn-3:/opt/starrocks/udf-jars$ ls -la
total 1396
drwxrwsrwx 2 root starrocks 4096 Jun 10 18:34 .
drwxr-xr-x 1 starrocks starrocks 4096 Jun 10 18:34 ..
-r--r--r-- 1 starrocks starrocks 1419104 Jun 10 18:34 starrocks-geo-udf-all-1.1.jar
starrocks@kube-starrocks-cn-3:/opt/starrocks/udf-jars$ jar -tf starrocks-geo-udf-all-1.1.jar | grep LatLonToH3UDF
udfs/LatLonToH3UDF.classRocky
06/10/2026, 6:53 PMfile:///, StarRocks requires the JAR file to be present at that exact same path on every FE node and every CN node in the cluster.
The "Analyzing error" you are seeing is likely coming from the FE (Frontend). Before the query even reaches the CN, the FE must load the JAR to inspect the class, verify the method signature (the types of arguments and return value), and validate the symbol. If the FE cannot find the file on its own local disk, it throws the "Class not found" error.
How to verify
Run this command against your FE pod(s):
bash
kubectl exec -it <your-fe-pod-name> -- ls -la /opt/starrocks/udf-jars/starrocks-geo-udf-all-1.1.jar
If this returns "No such file or directory," that is your culprit.
Solutions
1. The "Correct" Way (HTTP)
Upload the JAR to a location accessible via HTTP (like an S3 bucket, Artifactory, or even a simple Nginx pod).
sql
CREATE FUNCTION ...
PROPERTIES (
"symbol" = "udfs.LatLonToH3UDF",
"type" = "StarrocksJar",
"file" = "<http://my-internal-server/udfs/starrocks-geo-udf-all-1.1.jar>"
);
* Why: When you use an HTTP URL, the FE downloads it once to analyze it, and the CNs download and cache it locally when they need to run it. You don't have to manually sync files to any pods.
2. The "Manual" Way (If you must stay with file:///)
If you cannot use HTTP, you must:
1. Copy the JAR into every FE pod at /opt/starrocks/udf-jars/.
2. Ensure the JAR is in every CN pod (not just node 3).
3. Ensure the starrocks user has read permissions on all nodes.
Summary
The file:/// method still works in 4.1.1, but it is fragile because it assumes a perfectly mirrored filesystem across all pods. Since you are in Kubernetes, unless you are using a Shared Persistent Volume (RWX) mounted to all pods at that path, file:/// will almost always fail on the FE or a different CN node.
References
• sql-reference/sql-functions/JAVA_UDF.md
• sql-reference/sql-statements/Function/CREATE_FUNCTION.md
• administration/management/FE_configuration.md
• deployment/deploy_manually.md
References
• sql-reference/sql-functions/JAVA_UDF.md
• sql-reference/sql-statements/Function/CREATE_FUNCTION.md
• administration/management/FE_configuration.md
• deployment/deploy_manually.md
References
• sql-reference/sql-functions/JAVA_UDF.md
• sql-reference/sql-statements/Function/CREATE_FUNCTION.md
• administration/management/FE_configuration.md
• administration/management/BE_configuration.md
• deployment/deploy_manually.md
• sql-reference/System_variable.md
• faq/Others.md
• knowledge/trouble_shooting/fe_memory_problems.mdGregM
06/10/2026, 6:55 PMstarrocks@kube-starrocks-fe-2:/opt/starrocks/udf-jars$ ls -la
total 12
drwxrwsrwx 2 root starrocks 4096 Jun 10 18:34 .
drwxr-xr-x 1 starrocks starrocks 4096 Jun 10 18:34 ..
-r--r--r-- 1 starrocks starrocks 297 Jun 10 18:34 starrocks-geo-udf-all-1.1.jar
starrocks@kube-starrocks-fe-2:/opt/starrocks/udf-jars$ jar -tf starrocks-geo-udf-all-1.1.jar | grep LatLonToH3UDF
java.util.zip.ZipException: zip END header not found
at java.base/java.util.zip.ZipFile$Source.findEND(ZipFile.java:1637)
at java.base/java.util.zip.ZipFile$Source.initCEN(ZipFile.java:1645)
at java.base/java.util.zip.ZipFile$Source.<init>(ZipFile.java:1483)
at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1445)
at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:717)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:251)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:180)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:151)
at jdk.jartool/sun.tools.jar.Main.list(Main.java:1503)
at jdk.jartool/sun.tools.jar.Main.run(Main.java:368)
at jdk.jartool/sun.tools.jar.Main.main(Main.java:1681)Rocky
06/10/2026, 6:56 PM1,419,104 bytes (~1.4 MB).
* On your FE node: 297 bytes.
A 297-byte file is not a valid Java JAR (which is why jar -tf threw the ZipException). In Kubernetes environments, this specific behavior usually happens for one of two reasons:
1. The ConfigMap Size Limit (Most Likely)
If you are deploying this JAR via a Kubernetes ConfigMap, you have hit the 1MB limit. Kubernetes ConfigMaps and Secrets have a strict 1MB size limit. When you try to put a 1.4MB JAR into a ConfigMap, it either fails to apply or gets truncated/corrupted, resulting in that tiny file you see.
2. Failed kubectl cp
If you used kubectl cp to move the file, it may have disconnected mid-transfer, leaving a partial file.
How to fix this
Option A: Use a real HTTP source (Highly Recommended)
Since you are in Kubernetes, don't try to sync files manually. It's the "anti-pattern" for distributed databases.
1. Upload the JAR to any internal HTTP server, S3 bucket, or MinIO.
2. Register the UDF using the URL:
sql
CREATE FUNCTION ... PROPERTIES ("file" = "<http://minio.svc.cluster.local/jars/starrocks-geo-udf-all-1.1.jar>", ...);
StarRocks FE and CNs will download the file themselves, bypassing the 1MB K8s limit.
Option B: Use a Persistent Volume (Shared Storage)
If you have a Shared Volume (like EFS, Longhorn, or any NFS-backed PVC) mounted to both your FEs and CNs at `/opt/starrocks/udf-jars`:
1. Place the JAR file once in that shared volume.
2. Because it's the same physical storage, all pods will see the full 1.4MB file.
Option C: Manual kubectl cp (Quick Fix)
If you just want to test right now, manually copy the file from your local machine to the FE pod:
bash
kubectl cp starrocks-geo-udf-all-1.1.jar <fe-pod-name>:/opt/starrocks/udf-jars/starrocks-geo-udf-all-1.1.jar
Then run the ls -la command again on the FE to ensure the size is exactly 1,419,104 bytes before running the CREATE FUNCTION statement.
Summary: The FE is the "brain" that validates the UDF. If the FE's copy of the JAR is broken (even if the CN's copy is fine), the CREATE FUNCTION command will fail every time.GregM
06/10/2026, 6:56 PMRocky
06/10/2026, 6:57 PMkubectl cp
If you manually copied the JAR into the FE pod using kubectl cp, re-deploying the pod will delete the file entirely. Kubernetes pods have ephemeral filesystems; any manual changes made inside a running pod are wiped out when the pod restarts or re-deploys. You would end up with a "File not found" error instead of a "Class not found" error.
2. If you used a ConfigMap or Secret
If you are mounting this JAR via a Kubernetes ConfigMap or Secret, re-deploying will simply mount the same 297-byte corrupted file again.
* The Culprit: Kubernetes ConfigMaps have a strict 1MB size limit.
* The Symptom: When you try to store a 1.4MB JAR in a ConfigMap, Kubernetes often truncates the data or fails to encode it properly, resulting in a tiny, broken file (like your 297-byte result).
3. Why the FE is the "Gatekeeper"
Even if the JAR is perfect on your CN nodes, the CREATE FUNCTION command must run on the FE first. The FE acts as the gatekeeper: it opens the JAR, validates the Java class exists, checks the method signatures, and calculates a checksum. Because your FE has a corrupted 297-byte file, it can't "unzip" the JAR to see the class, so it fails before the CN ever gets a chance to try.
──────────
The Recommended Path Forward
Step 1: Abandon file:/// for Kubernetes
The file:/// method is meant for legacy bare-metal installs. In Kubernetes, the "StarRocks way" is to use an HTTP URL.
1. Host your JAR on a simple internal service (e.g., a MinIO bucket, an Nginx pod, or even a public GitHub release link).
2. Run your SQL like this:
sql
CREATE FUNCTION h3_lat_lon_to_cell(DOUBLE, DOUBLE, INT)
RETURNS BIGINT
PROPERTIES (
"symbol" = "udfs.LatLonToH3UDF",
"type" = "StarrocksJar",
"file" = "<http://your-file-server/starrocks-geo-udf-all-1.1.jar>"
);
* Result: The FE will download the full JAR into its own internal cache, and the CNs will do the same when they need it. No manual syncing or K8s size limits required.
Step 2: If you must use local files (The "PVC" Way)
If security policies prevent HTTP, you must use a Persistent Volume (PV) with ReadWriteMany (RWX) access:
1. Mount the same PVC to /opt/starrocks/udf-jars/ on both your FE and CN pod templates.
2. Place the JAR into that volume once.
3. Because it's a real disk volume, it won't hit the 1MB ConfigMap limit and it won't disappear when you re-deploy.
Summary: Your current error is caused by a corrupted JAR on the FE. Re-deploying won't fix a truncated ConfigMap or a manual file copy. Switch to an HTTP URL to resolve this instantly.
References
• administration/management/BE_configuration.md
• sql-reference/sql-functions/JAVA_UDF.md
• administration/management/FE_configuration.md
• sql-reference/sql-functions/Python_UDF.mdGregM
06/11/2026, 2:12 PMFail to publish partition 2822666 error Fail to publish version for tablets:[[2822672, 2822668, 2822670]], error msg: prepare_primary_index: load primary index failed: Not found: load_segments failed tablet:2822670 rowset:19 segid:0: starlet err Object https://<storage_account>/dataops-k8-blob/starrocks/c06faf1f-a109-4cf6-a569-f20a4df260be/db49953/2618536/2822666/data/0000000000216206_1476812a-dfaa-4f78-aa2a-538c72d13ee1.dat does not exist
be/src/storage/lake/rowset.cpp:481 load_segments(&segments, false), host: kube-starrocks-cn-0.kube-starrocks-cn-search.kube-starrocks.svc.cluster.local
this happened recently so it's a good time to debug. I need to figure this out if we plan to continue using starrocks.Rocky
06/11/2026, 2:12 PM.dat) that no longer exists in your Azure Blob storage.
The error prepare_primary_index: load primary index failed happens because, in Primary Key tables, the system must load the Primary Index from existing rowsets to apply new updates. If a single segment is missing, the index cannot be built, and the "publish" phase of your transaction fails.
Why this happened
In shared-data clusters, this typically occurs due to:
1. Compaction/GC Race: A bug in the Garbage Collection (GC) logic might have cleaned up a segment that was still being referenced by a tablet version.
2. Metadata Inconsistency: During your upgrade from 4.0.9 to 4.1.1, a Leader FE switch or a compaction task might have committed metadata that pointed to a file that wasn't fully persisted or was prematurely deleted.
3. Manual Deletion: Accidental manual cleanup in the Azure storage account.
How to fix it (StarRocks 4.1.1)
Since you are on version 4.1.1, you can use the new Cloud-Native Table Repair feature. This mechanism scans historical metadata versions to find the most recent "healthy" state where all files still exist and rolls the affected tablets back to that version.
1. Identify the affected Partition
Find the partition name for the ID mentioned in your error (2822666):
sql
SELECT TABLE_NAME, PARTITION_NAME
FROM information_schema.partitions_meta
WHERE PARTITION_ID = 2822666;
2. Run the Repair Command
Execute the following to roll back the corrupted tablets to their last known good version:
sql
ADMIN REPAIR TABLE <your_table_name> PARTITION (<your_partition_name>);
* Strict Consistency (Default): This will find the latest version that is valid for all tablets in the partition and roll them all back to that point.
* Maximum Availability: If you want to keep as much data as possible even if tablets end up at slightly different versions, use:
sql
ADMIN REPAIR TABLE <your_table_name> PARTITION (<your_partition_name>)
PROPERTIES ("enforce_consistent_version" = "false");
3. Verify the Status
Check if the repair was successful:
sql
ADMIN SHOW REPLICA STATUS FROM <your_table_name> PARTITION (<your_partition_name>);
Important Notes
* Data Loss: This repair works by rolling back metadata. You will lose the data that was loaded between the corrupted version and the healthy historical version. You may need to re-ingest recent data for that partition.
* Stability: If this continues to happen after the repair, check your FE configuration lake_gc_expire_seconds. If it is set too low (e.g., less than 86400), long-running compactions or transactions might lose files to the GC.
* Bug in 4.1.1: Version 4.1.x introduced significant changes to shared-data metadata management. If the ADMIN REPAIR fails, it is highly recommended to check the FE leader logs for lake or publish related exceptions and consider reporting this as a potential regression in the 4.1.x branch.
References
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_REPAIR.md
• administration/management/resource_management/Replica.md
• administration/management/compaction.md
• faq/shared_data_faq.md
• table_design/table_types/primary_key_table.md
References
• faq/loading/Loading_faq.mdRocky
06/11/2026, 2:12 PMGregM
06/11/2026, 2:18 PMlake_gc_expire_seconds doesn't appear to be a real configRocky
06/11/2026, 2:19 PMlake_gc_expire_seconds is not a valid configuration parameter in StarRocks. I likely conflated the names of several similar shared-data (lake) parameters.
The actual parameters that control Garbage Collection (GC) and version retention in shared-data mode are:
1. lake_autovacuum_grace_period_minutes (Most Relevant)
* Default: 30 (minutes)
* Description: This is the "safe zone." It determines how long historical data versions (and their corresponding segment files) are kept after a Compaction has successfully created a new version.
* Why it matters for your error: If a Primary Key table is performing a heavy load or a long-running Compaction, the system needs to "look back" at previous segments to build the Primary Index. If this is set too low (e.g., the default 30 minutes) and your operations take longer than that, the AutoVacuum process might delete the segment file while the FE/CN is still trying to reference it, leading to the Object does not exist error.
* Recommendation: If you are seeing "Object does not exist" errors during publish, try increasing this to 60 or 120 in your FE config.
2. lake_autovacuum_stale_partition_threshold
* Default: 12 (hours)
* Description: If a partition hasn't been updated (no loads, deletes, or compactions) within this timeframe, the system stops performing AutoVacuum on it.
3. shard_group_clean_threshold_sec
* Default: 3600 (1 hour)
* Description: The time FE waits before cleaning up unused tablet and shard groups.
4. catalog_trash_expire_second
* Default: 86400 (24 hours)
* Description: How long metadata is kept in the "recycle bin" after you manually run DROP TABLE or DROP DATABASE.
──────────
Summary for your "Object does not exist" issue:
The error you encountered is a known "race condition" in shared-data mode where the Garbage Collector is too aggressive for the speed of your Primary Key index builds.
Immediate Fixes:
1. Use ADMIN REPAIR TABLE <name> PARTITION (<p_name>); to roll back the corrupted metadata to a healthy state.
2. Increase lake_autovacuum_grace_period_minutes in your FE configuration to give the system more breathing room during heavy loads.
3. Since you just upgraded to 4.1.1, check if there are any lake_compaction tasks that are failing or stuck in the FE leader logs, as failed compactions can sometimes trigger premature cleanup.
References
• administration/management/FE_configuration.md
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_REPAIR.md
• faq/shared_data_faq.md
• administration/management/compaction.md
References
• administration/management/FE_configuration.mdGregM
06/11/2026, 3:03 PMRocky
06/11/2026, 3:04 PM.dat file.
The error starlet err grpc.GetShard(...) error: Deadline Exceeded means that your FE (Leader) tried to communicate with a CN node (via the "Starlet" service) to manage metadata for that partition, but the request timed out before the CN could respond.
How this causes the "Missing .dat" error
In StarRocks' shared-data architecture, there is a delicate dance between Compaction (which creates new files and marks old ones for deletion) and Autovacuum (which actually deletes those old files).
1. The Bottleneck: If your CN nodes or FE are under heavy load (CPU spikes, memory pressure, or IO throttling on Azure Blob), these internal metadata requests start timing out (Deadline Exceeded).
2. The Inconsistency: When these RPCs time out during critical "Publish" or "Vacuum" phases, the system can get into a state where the Metadata thinks a file should exist, but the Physical Storage cleanup was either triggered prematurely or the write was never fully acknowledged due to the timeout.
3. Primary Key Sensitivity: Primary Key tables are especially vulnerable because they must load the primary index from these files. If one .dat file is missing due to an inconsistent metadata update, the entire partition becomes unreadable.
How to fix and prevent this
1. Reduce Autovacuum Pressure
If the system is timing out, it's often because it's trying to do too much cleanup at once. You can throttle the Autovacuum daemon by adding these to your FE configuration (fe.conf):
properties
# Lower the number of partitions vacuumed at once (Default is 8)
lake_autovacuum_parallel_partitions = 4
# Increase the interval between vacuuming the same partition (Default is 180s)
lake_autovacuum_partition_naptime_seconds = 300
2. Increase the "Grace Period"
As mentioned before, increasing the time a file is kept after it is "no longer needed" gives the system a safety buffer in case of timeouts:
properties
# Give the system more time before deleting old segments (Default is 30)
lake_autovacuum_grace_period_minutes = 60
3. Check for Azure Throttling or CN Resource Exhaustion
* CN Load: Check the CPU and Memory usage on your kube-starrocks-cn-0 pod at the time of the error (00:16:57Z). If CPU was at 100%, the GetShard gRPC request was likely stuck in a queue.
* Azure Blob: Ensure your storage account isn't hitting ingress/egress limits. StarRocks shared-data performance is heavily tied to the latency of the object store.
4. The "Immediate" Fix for the Table
Since the .dat file is already gone, the partition is currently "broken." You must run the repair command to tell StarRocks to ignore the corrupted metadata version and roll back to the last version where all files existed:
sql
-- This will roll the partition back to its last healthy state
ADMIN REPAIR TABLE <mytable> PARTITION (p2822666);
Summary
The Deadline Exceeded proves your cluster is struggling to keep up with metadata management. This upgrade to 4.1.1 likely increased the volume of internal metadata traffic. Throttling the Autovacuum and increasing the Grace Period are your best defenses against this happening again.
References
• faq/Sql_faq.md
• faq/shared_data_faq.md
• faq/loading/Loading_faq.md
• knowledge/usage/best-practice.mdGregM
06/11/2026, 3:09 PMRocky
06/11/2026, 3:10 PMDeadline Exceeded error), the daemon simply moves on to the next partition. It will attempt to vacuum your partition again in the next cycle, which is governed by the lake_autovacuum_partition_naptime_seconds (default 180 seconds).
So, the system will try again, but only after the "nap time" has passed for that specific partition.
2. The "Object Not Found" Paradox
There is a subtle danger here:
* If the vacuum fails (Deadline Exceeded), it usually means it didn't finish deleting files. This is generally "safe" (you just have extra junk in storage).
* However, if you are seeing Object does not exist errors, it means a vacuum task (or a compaction job) succeeded in deleting a file that the Primary Index still believed was necessary.
In StarRocks 4.1.x, this often happens because:
1. Metadata vs. Physical Reality: A previous vacuum cycle might have completed successfully, but due to the high load (indicated by your timeouts), the FE's metadata state and the actual files in Azure Blob became desynchronized.
2. Primary Key Compaction: In version 4.1.1, Primary Key tables use a more aggressive metadata management system. If the GetShard call timed out during a compaction or publish phase, the system might have inconsistent pointers to data segments.
3. Why the "Deadline Exceeded" is a warning sign
Even though the vacuum retries, the fact that it is timing out suggests your FE/CN communication is saturated. When the Autovacuum daemon hits a deadline, it can leave "stale" metadata behind. If a subsequent load or compaction tries to reference a segment that was partially processed or incorrectly flagged for deletion during that timed-out window, you get the Not found error.
Recommendations
* Don't wait for the retry to fix the "Not Found" error: A retry of the vacuum will not bring back the deleted .dat file. The vacuum only deletes; it never restores.
* Use ADMIN REPAIR: This is your only way to fix the current "Not Found" error. It tells the metadata to "rewind" to a version where that file still existed.
* Increase Timeout: If you see frequent Deadline Exceeded, you can increase the internal RPC timeout (though this is a BE/CN config and usually handled via lake_service_rpc_timeout_ms in newer versions, it's safer to first reduce the load via the FE configs mentioned previously).
Summary: The vacuum retries every 3 minutes, but the "missing file" error is a permanent state of the current metadata version that requires a manual ADMIN REPAIR or a rollback.
References
• administration/management/FE_configuration.md
• faq/shared_data_faq.md
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_REPAIR.md
References
• administration/management/FE_configuration.md
• faq/shared_data_faq.md
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_REPAIR.md
References
• administration/management/FE_configuration.md
• faq/shared_data_faq.mdRocky
06/11/2026, 3:10 PMGregM
06/11/2026, 3:32 PMRocky
06/11/2026, 3:32 PMAutovacuumDaemon in the Leader FE runs a continuous loop. Here is why those errors disappear:
1. The "Nap Time": When a vacuum task for a partition fails (due to a Deadline Exceeded or any other error), the daemon marks that partition as "done for now." It then waits for the duration of lake_autovacuum_partition_naptime_seconds (default: 180 seconds).
2. The Next Cycle: Once those 3 minutes are up, the partition becomes eligible for vacuuming again. The daemon will pick it up, recalculate what needs to be deleted, and try the RPC call again.
3. Silence = Success: If you don't see the error again for those partitions, it means the subsequent retry succeeded. The "Deadline Exceeded" was likely caused by a temporary spike in network latency or CN CPU usage that cleared up by the time the next 3-minute window arrived.
Why this is both Good and Bad
* The Good: The system is self-healing. A temporary timeout doesn't cause a permanent leak of storage space; it just delays the cleanup by a few minutes.
* The Bad: The fact that you are seeing these warnings at all means your FE-to-CN communication (the Starlet gRPC service) is hitting its limits.
Why you have a "Missing .dat" file but others are fine
This is the critical distinction:
* Failed Vacuum (The log you saw): The system tried to delete old files but timed out. The files are still there. This is safe.
* Successful Vacuum + Timing Race: The "Object does not exist" error happens when a vacuum succeeds in deleting files that the Primary Key index (on a different node or in a different thread) still thinks it needs.
Recommended Action
Since you are seeing these "Deadline Exceeded" warnings across multiple partitions, your cluster's metadata management is "running hot." You should increase the RPC timeout to give these tasks more time to complete before they error out:
In your FE config (fe.conf):
properties
# Increase internal metadata RPC timeout (Default is usually 5s)
starmgr_grpc_timeout_seconds = 10
This will reduce the number of "Vacuumed with error" warnings in your logs and allow the background cleanup to finish even when the system is under heavy load.
References
• administration/management/FE_configuration.md
• faq/shared_data_faq.md
• administration/management/compaction.md
• administration/management/BE_configuration.md
References
• administration/management/FE_configuration.md
• faq/operation_maintenance_faq.md
• administration/management/compaction.md
• faq/shared_data_faq.mdGregM
06/11/2026, 3:35 PMRocky
06/11/2026, 3:36 PMstarmgr_grpc_timeout_seconds is already set to 60 seconds and you are still hitting Deadline Exceeded, this is a significant red flag. A metadata operation like GetShard should typically take milliseconds; timing out after a full minute indicates a fundamental bottleneck rather than a simple configuration issue.
What a 60-second timeout implies
If the system is exhausting a 60-second window, increasing the timeout further is unlikely to help. It suggests one of the following:
1. CN Node Resource Exhaustion: The CN pod (likely kube-starrocks-cn-0) is so overloaded that the gRPC request is sitting in a queue for over a minute before a worker thread can even look at it. Check the CPU and Memory usage of your CN pods specifically at 00:16:57Z.
2. IO Stall (Azure Blob): The GetShard call might be waiting for the CN to fetch or verify something on Azure Blob. If Azure is heavily throttling your storage account or if there's a networking "black hole," the thread will hang until the deadline.
3. FE Global Lock Contention: If the FE (Leader) is busy with a massive metadata update (like a very large ALTER TABLE or hundreds of concurrent PUBLISH tasks), the AutovacuumDaemon might be blocked from even sending the request or processing the result.
4. Thread Pool Exhaustion: Both the FE and CN have gRPC thread pools. If these are full, new requests wait.
How to address the "60-Second Deadline"
1. Throttle the Vacuum Concurrency
Instead of letting the vacuum tasks wait longer, make them happen less frequently and with less concurrency. This reduces the "queue" on the CN nodes.
Add/Update in `fe.conf`:
properties
# Reduce concurrent vacuum tasks from default 8 to 2 or 4
lake_autovacuum_parallel_partitions = 2
# Slow down the retry cycle (increase "nap time" between attempts)
lake_autovacuum_partition_naptime_seconds = 600
2. Check for "Long GC" in FE/CN Logs
Search your FE and CN logs for [GC pause] or Slow execution. If the Java process (FE) or the C++ backend (CN) is experiencing long pauses, it can't respond to gRPC heartbeats or requests, leading to a timeout.
3. Monitor CN "Starlet" Health
In your CN pod, check the <http://cn.INFO|cn.INFO> or <http://starlet.INFO|starlet.INFO> logs for errors around the same timestamp. Look for:
* Rejected request (indicates lake_service_max_concurrency hit).
* Storage error (indicates Azure Blob issues).
4. The "Safety Buffer" (Crucial)
Since you are seeing these timeouts, your metadata and storage are in a "race condition." You must increase the grace period to ensure that even if a vacuum is delayed or retried, it doesn't delete files that are still being referenced by slow-moving metadata tasks.
Update in `fe.conf`:
properties
# Keep files for 2 hours instead of 30 mins to account for these 60s+ lags
lake_autovacuum_grace_period_minutes = 120
Summary of the Fix
The fact that you see these warnings on other partitions without errors later confirms the self-healing nature of the vacuum—it eventually succeeds on a retry. However, the one partition that failed with a "missing file" error likely had its files deleted by a different successful vacuum/compaction task while the GetShard call for that specific version was still hung/timing out.
Immediate Action:
1. Run ADMIN REPAIR TABLE <mytable> PARTITION (p2822666); to restore the broken partition.
2. Reduce lake_autovacuum_parallel_partitions to 2 to stop the cluster from choking on its own cleanup tasks.
3. Increase lake_autovacuum_grace_period_minutes to 120 to prevent future "Not Found" errors during these lag spikes.
References
• administration/management/FE_configuration.md
• faq/shared_data_faq.md
• administration/management/compaction.mdRocky
06/11/2026, 3:36 PMGregM
06/11/2026, 3:44 PMRocky
06/11/2026, 3:44 PMDeadline Exceeded errors you are seeing in your logs.
What these metrics tell you:
* Vacuum Deletes (Latency/QPS): This tracks how long the CN takes to process the vacuum request from the FE. If the "Quantile Latency" (e.g., P99) spikes toward or above your starmgr_grpc_timeout_seconds (60s), the FE will abort the task and throw the Deadline Exceeded error.
* Vacuum Errors: In the same "Vacuum" section of the dashboard, you should see a corresponding spike in the Errors chart whenever a timeout occurs.
Why the CN is showing spikes:
Since the vacuum process involves the CN physically deleting files from Azure Blob storage, a latency spike on the CN usually means one of three things:
1. Storage Throttle: Azure Blob might be throttling the delete requests (TPS limits).
2. CN Resource Saturation: The CN's "Starlet" worker threads are overwhelmed, causing requests to sit in the queue.
3. Large Batch Size: If a single partition has a massive number of files to clean up, the "delete" RPC might simply be too large to complete within 60 seconds.
Other Metrics to cross-reference:
To narrow down why that specific CN is lagging, check these on the Starlet Dashboard:
* FSLIB FS METRICS -> filesystem meta operations: Look for spikes in directory listing or file deletion operations.
* S3/Azure IO METRICS: Look for high latency in backend storage calls. If Azure latency is high, the StarRocks vacuum will naturally slow down.
Recommendation:
If these spikes are frequent, the system is struggling to keep up with the volume of garbage data. Reducing lake_autovacuum_parallel_partitions to a lower number (like 2) will reduce the concurrent pressure on that CN, smoothing out those latency spikes and preventing the timeouts.
References
• administration/management/monitoring/metrics-shared-data.md
• faq/shared_data_faq.md
• administration/management/FE_configuration.md
References
• administration/management/monitoring/metrics-shared-data.md
• faq/shared_data_faq.md
• deployment/shared_data/feature-support-shared-data.md
• using_starrocks/caching/block_cache.md
• administration/management/BE_configuration.mdGregM
06/11/2026, 4:01 PMW20260611 14:13:34.124416 140377747093184 lake_service.cpp:381] Fail to publish version: Internal error: prepare_primary_index: load primary index failed: Not found: load_segments failed tablet:2822672 rowset:18 segid:0: starlet err Object <my_storage_account>
dataops-k8-blob/starrocks/c06faf1f-a109-4cf6-a569-f20a4df260be/db49953/2618536/2822666/data/0000000000216206_dbd759c1-b756-4f39-91e6-7a7326797513.dat does not exist
be/src/storage/lake/rowset.cpp:481 load_segments(&segments, false)
be/src/storage/lake/txn_log_applier.cpp:476 value_or_err_L476
be/src/storage/lake/txn_log_applier.cpp:509 prepare_primary_index()
be/src/storage/lake/txn_log_applier.cpp:310 check_and_recover([&]() { return apply_write_log(log.op_write(), log.txn_id()); }). tablet_info={tablet_id: 2822672} txn_ids=txn_id: 2209426
commit_time: 1781186401
combined_txn_log: true
txn_type: TXN_NORMAL
force_publish: false
gtid: 426455023854026752
version=30Rocky
06/11/2026, 4:01 PM.dat file) to resolve updates/deletes.
3. The Root Cause: The CN asked for the file, but it was already gone from Azure Blob Storage (starlet err Object ... does not exist).
4. The Link to your previous warnings: Your vacuum tasks were timing out ("Deadline Exceeded"), but as you suspected, they retried. One of those retries succeeded and deleted this .dat file because it thought the file was old/garbage. However, because your system is experiencing high latency (those 60s spikes you saw in Grafana), the Publish task for Transaction 2209426 was still running and actually still needed that "old" file to finish building the new index version.
The vacuum was "too fast" (or the publish was "too slow"), and it deleted the floor while the publish task was still standing on it.
──────────
Critical Actions
1. Immediate Recovery (The "Bad" News)
Because a .dat file is physically missing from Azure Blob, this partition (2822666) is now corrupted.
* ADMIN REPAIR will likely not work because there is no other copy of the file in shared storage to "repair" from.
* You must reload the data for this partition.
* If possible, TRUNCATE PARTITION p2822666; and re-run the ingestion for that time range.
* If you cannot reload, you may have to drop and recreate the partition, but the data in that specific .dat file is effectively lost.
2. Emergency Config Changes (The Prevention)
You need to stop the vacuum from being so aggressive while your CNs are struggling with latency.
In fe.conf, set these immediately:
properties
# 1. Increase the safety buffer from 30 mins to 2 hours.
# This ensures files are kept much longer after they are "replaced,"
# giving slow Publish tasks plenty of time to finish.
lake_autovacuum_grace_period_minutes = 120
# 2. Reduce the number of partitions being vacuumed at once.
# This reduces the IO load/spikes on your CN nodes.
lake_autovacuum_parallel_partitions = 2
# 3. Increase the "nap" time between vacuum attempts.
lake_autovacuum_partition_naptime_seconds = 600
3. Why the Latency Spikes?
The "60-second latency spikes" you see in Grafana are the root of all this. Since you are on Azure:
* Check if you are hitting Azure Storage Account Egress/Ingress limits or Request Rate limits (TPS).
* If your CNs are in Kubernetes, check if they are being CPU throttled (Cgroup throttles). If the CN is throttled, it can't process the gRPC heartbeats, leading to the "Deadline Exceeded" and the subsequent "Not Found" race condition.
Summary
The "Deadline Exceeded" warnings you saw earlier were the system's way of telling you it was struggling. Because the vacuum eventually succeeded while a related publish task was still lagging, it deleted a required file. Increase your lake_autovacuum_grace_period_minutes immediately to prevent this from happening to other partitions.
References
• administration/management/FE_configuration.md
• faq/shared_data_faq.md
• administration/management/monitoring/metrics-shared-data.md
• sql-reference/sql-statements/table_management/TRUNCATE_TABLE.md
)
ReferencesRocky
06/11/2026, 4:01 PMGregM
06/11/2026, 4:09 PMRocky
06/11/2026, 4:09 PMstarmgr_grpc_timeout_seconds usually applies to the CN talking to the FE's StarManager (metadata service). If the FE is under heavy load (e.g., a massive metadata update or a Java GC pause), it won't respond to the CN's request for metadata. The CN waits 60s and then logs "Deadline Exceeded."
Conclusion: The CN is physically fast, but the coordination between FE and CN is "choking."
2. The Log Analysis: Not found: load_segments failed
This error in lake_service.cpp:381 is the result of the timeout you’re seeing.
* What happened: A transaction (Ingestion) reached the "Publish" phase. For a Primary Key table, the CN must load existing data segments to update the Primary Index.
* The Conflict: Because the FE was "choking" (the 60s timeout), the version tracking got out of sync. The AutoVacuum daemon (running on the FE) incorrectly identified the .dat file as "garbage" and deleted it because it thought no one was using it anymore.
* The Result: When the Publish task finally tried to read that file, it got the "Object does not exist" error.
3. Immediate Recommended Fixes
Since your execution is fast but your coordination is timing out, you need to reduce the "Metadata Noise":
A. Increase the Safety Buffer (Critical)
The vacuum is deleting files while they are still needed because the system is lagging. You must give the system more "thinking time."
In `fe.conf`:
properties
# Double the grace period so files aren't eligible for deletion for 1 hour.
# This prevents the "Not Found" error during 60s lag spikes.
lake_autovacuum_grace_period_minutes = 60
B. Throttling Vacuum Frequency
If the vacuum is triggering too many gRPC calls, it's contributing to the 60s queueing delay.
In `fe.conf`:
properties
# Default is usually 8. Lowering this reduces gRPC pressure on the FE.
lake_autovacuum_parallel_partitions = 2
# Let the vacuum "sleep" longer between rounds.
lake_autovacuum_partition_naptime_seconds = 300
C. Check FE Thread Health
If starmgr_grpc_timeout_seconds is being hit, check your FE logs (fe.log and fe.warn.log) for:
* Slow execution or Long GC pause
* starmgr related errors.
* Check FE Grafana: JVM GC Time and FE Edit Log Flush Latency. If the FE cannot flush its own logs to disk quickly, the metadata service (StarMgr) will hang, causing the 60s timeouts on the CNs.
Summary
Your partition 2822666 is currently corrupted because a required data file was deleted.
1. Stop the bleeding: Increase lake_autovacuum_grace_period_minutes to 60 or 120.
2. Fix the partition: You will likely need to TRUNCATE and reload the data for that specific partition, as the physical file is gone from Azure.
3. Monitor FE: Look at FE CPU and GC metrics; the 60s delay is almost certainly happening inside the FE metadata layer where the FE manages metadata, FE manages metadata, not in the CN's deletion logic.
References
• administration/management/FE_configuration.md
• administration/management/BE_configuration.mdRocky
06/11/2026, 4:09 PMGregM
06/11/2026, 4:39 PMRocky
06/11/2026, 4:39 PMlake_autovacuum_grace_period_minutes from 30 to 60 or 120, you are effectively keeping those "garbage" files for an extra 30–90 minutes.
* The Cost: Unless you are loading hundreds of Terabytes per hour, the cost of keeping a few extra versions of data for an hour on Azure Blob is typically just a few cents or dollars a month. It is much cheaper than the engineering time required to fix a corrupted partition.
2. Slower Reclaim of Space
If you are running a massive "one-time" data delete or a major schema change, the disk space in your storage account won't "shrink" immediately. You’ll have to wait for that grace period to pass before the physical .dat files are deleted.
3. Metadata Retention (Minimal Impact)
The StarRocks FE (FrontEnd) has to track these "stale" versions in its memory and image until they are vacuumed.
* If you set this to something extreme (like 1 week), your FE image size would grow significantly, and it could slow down FE restarts.
* Moving from 30 minutes to 2 hours has almost zero noticeable impact on FE metadata performance.
4. Reduced Vacuum "Throughput"
By lowering lake_autovacuum_parallel_partitions and increasing naptime, you are intentionally slowing down the cleanup process.
* The Risk: If your ingestion rate is extremely high (thousands of transactions per minute), garbage might accumulate faster than the vacuum can clean it up.
* How to monitor: Keep an eye on the "Garbage File Size" or "Garbage File Count" in the Shared-data Grafana dashboard. If you see this number trending up indefinitely over 24 hours, you’ve slowed the vacuum down too much.
Recommendation
For your current situation—where you are actually losing data because the vacuum is "outrunning" the metadata coordination—*the benefits far outweigh the downsides.*
* Set lake_autovacuum_grace_period_minutes = 60 (or 120).
* Set lake_autovacuum_parallel_partitions = 4 (half of default).
This "buys" your system time to handle those 60-second latency spikes without the vacuum daemon accidentally deleting a file that a slow task is still trying to read.
References
• administration/management/FE_configuration.md
• knowledge/admin_and_operation/shared_data_garbage_cleanup.md
• administration/management/monitoring/metrics-shared-data.md
• best_practices/primarykey_table.md
References
• administration/management/FE_configuration.md
• administration/management/compaction.md
• knowledge/admin_and_operation/shared_data_compaction.md
• best_practices/primarykey_table.mdGregM
06/11/2026, 4:43 PMRocky
06/11/2026, 4:43 PMstarrocks_be_segment_file_not_found_total: This tracks how many times a CN tried to open a file that was missing from storage. In a healthy cluster, this should be 0. A rising line here confirms that your vacuum is deleting files that the system still needs (the race condition we discussed).
2. Monitoring the "Backlog" (Indirectly)
Instead of a single "size" metric, use the Compaction Score to see if garbage is building up. When data is loaded or updated, StarRocks creates new versions. Until compaction merges them and vacuum deletes the old ones, those "stale" versions are essentially garbage.
* Query: SELECT DB_NAME, TABLE_NAME, MAX_CS, AVG_CS FROM information_schema.partitions_meta WHERE MAX_CS > 10;
* Interpretation: A high Max_CS (Compaction Score) means that partition has many historical data files. If this number stays high for hours despite your vacuum running, it means the vacuum is failing or is too slow to keep up.
3. Monitoring Vacuum Activity
Check these in your Shared-data Dashboard (or raw Prometheus):
* starrocks_fe_lake_vacuum_deletes_total: This is a counter. If it’s flat, your vacuum isn't doing anything.
* starrocks_fe_lake_vacuum_errors_total: If this is increasing, the vacuum tasks are failing (likely due to the 60s gRPC timeouts you saw).
* starrocks_fe_lake_vacuum_duration_ms: Compare this to your 60s timeout. If it's consistently hitting the ceiling, you need to increase your starmgr_grpc_timeout_seconds or reduce parallel vacuum tasks.
4. How to see the "Real" Garbage Amount
If you need to know exactly how many GBs of garbage are in your Azure container, you have two options:
1. Manual Comparison: Compare the output of SHOW DATA (which only shows the latest visible version) with the total size of the container reported by the Azure Portal.
_ _Example:* If Azure says 10TB and SHOW DATA says 2TB, you have 8TB of historical versions/garbage.
2. Audit Tool: StarRocks provides a meta_tool.sh that can perform a lake_datafile_gc operation with do_delete=false. It will scan your metadata and your Azure Blob and output exactly which files are unreferenced (garbage).
Summary for your Dashboard
To prevent the "Not Found" error you experienced, monitor starrocks_be_segment_file_not_found_total and the Compaction Scores in partitions_meta. If the scores are high and the "Not Found" errors are non-zero, it means your vacuum is too aggressive relative to your system's metadata latency.
References
• administration/management/monitoring/metrics-shared-data.md
• administration/management/monitoring/metrics.md
• faq/shared_data_faq.md
• knowledge/admin_and_operation/shared_data_garbage_cleanup.md
• deployment/shared_data/feature-support-shared-data.md
• sql-reference/sql-statements/Database/SHOW_DATA.md
References
• administration/management/monitoring/metrics.mdRocky
06/11/2026, 4:43 PMGregM
06/11/2026, 8:29 PM.dat popped up. What's really curious is I have a different ETL process that is constantly running and has been fine but this one hasn't run for an hour and does this.Rocky
06/11/2026, 8:30 PMload_segments).
* The Bug/Race: If the vacuum process ran during that idle hour, it might have deleted files that the FE still considers part of the "latest version" due to a metadata lag or a "stale" view of the tablet's history.
* Why the "Always-on" ETL is fine: Because that process is constantly writing, its index is always "hot" in memory, and its metadata is constantly being refreshed in the CN's cache. The vacuum never gets a chance to "sneak in" and delete a file that isn't being actively held by a session.
2. Configuration Adjustment: lake_autovacuum_stale_partition_threshold
There is a specific parameter that controls when StarRocks stops vacuuming "idle" partitions:
* lake_autovacuum_stale_partition_threshold (Default: 12 hours).
* What this does: If a partition hasn't been updated for 12 hours, the vacuum daemon stops looking at it entirely.
* The Issue: Your partition is only idle for 1 hour, so it is still being "scanned" by the vacuum daemon every few minutes. If there's any discrepancy in your storage metadata (Azure Blob vs. FE), the vacuum daemon has many chances to accidentally flag an unreferenced file in that 1-hour window.
Recommendation: Try reducing this to a smaller window (e.g., 2 hours) to limit the time an idle partition is "exposed" to the vacuum daemon, or ensure it is high enough that the vacuum doesn't act on partitions you plan to resume shortly. However, usually, increasing the grace period (which you did) is the standard fix.
3. Check for "Metadata Lag" on the FE
If increasing the grace period to 60 minutes didn't stop the .dat files from disappearing, it means the FE believes a file is valid for > 60 minutes after it has actually been physically deleted, or vice versa.
* Check your fe.log for "starmgr" or "tablet manager" errors.
* Search for fail to commit txn or publish version timeout in the FE logs during the time the ETL was idle.
4. Enable Persistent Index (If not already enabled)
If your Primary Key table is large, the "rebuild" process after an hour of idleness is very heavy because it has to load all .dat files to recreate the index.
Setting the table property:
sql
ALTER TABLE your_table SET ("enable_persistent_index" = "true");
By enabling the persistent index, the index itself is stored in Azure Blob. This significantly reduces the need for the BE to "load segments" from the original data files when the ETL restarts, which can bypass the load_segments failed error.
5. Final Diagnostic Command
When the error happens, run this on the FE to see if the FE and the physical storage are out of sync:
sql
-- Replace with your actual tablet ID from the error log
SHOW TABLET <tablet_id>;
Check if the VisibleVersion in the output matches what you expect. If the VisibleVersion is very old but the files in Azure are gone, your FE's metadata journal might be stuck.
Summary of Action Plan:
1. Enable Persistent Index: This is the most robust way to stabilize Primary Key tables in shared-data mode.
2. Verify FE Health: Ensure the FE isn't hitting "Edit Log" or "BDBJE" pressure (look for HANDSHAKE_ERROR or ACK timeout in fe.log).Rocky
06/11/2026, 8:30 PMGregM
06/11/2026, 8:35 PMRocky
06/11/2026, 8:35 PMSELECT TABLE_NAME, MAX_CS FROM information_schema.partitions_meta WHERE TABLE_NAME = 'your_ugly_table';. If MAX_CS is significantly higher (e.g., > 30) than your stable tables, this is the cause.
2. Missing "Persistent Index" (Primary Key Tables Only)
If this is a Primary Key table, it is the most likely culprit.
* The Idle Eviction: When a PK table is idle for an hour, the Compute Nodes (CN) often evict the "Primary Key Index" from memory to save RAM.
* The Rebuild: When your ETL starts again, the CN has to rebuild that index. To do this, it must read every single segment file in the table.
* The Error: If the vacuum deleted even one historical segment that the FE still thinks is part of the current "version" during that idle hour, the index rebuild fails immediately with a missing .dat error.
* Fix: Ensure Persistent Index is enabled for this specific table. This stores the index on Azure Blob so the CN doesn't have to "re-read" all the .dat files after an idle period.
sql
ALTER TABLE your_ugly_table SET ("enable_persistent_index" = "true");
3. Too Many Tablets/Buckets
Check if this "ugly" dataset has a much higher bucket count than the others.
* If you have a small dataset but set BUCKETS 64 or 128, you are creating a massive amount of metadata for very little data.
* The Vacuum process works per tablet. If one table has 2,000 tablets and another has 20, the vacuum for the "ugly" table is under much higher "metadata pressure," making it more likely to hit a race condition or a gRPC timeout.
4. Data Cache Corruption
If you have Data Cache enabled on your CN nodes:
* Sometimes the cache on a specific CN keeps a "hot" pointer to a file path that was physically deleted from Azure Blob by the vacuum daemon.
* Why only this table? If this table is queried or updated by a specific set of CNs, those caches might be "stuck."
* Test: Try running set global enable_scan_datacache = false; before starting the ETL. If the error goes away, you need to clear the cache on your CN nodes (rm -rf the cache directory).
Summary Recommendation
1. Check Compaction Score: If it's high for this table, you need to increase the lake_autovacuum_grace_period_minutes even further (try 180) specifically for this table's heavy churn.
2. Enable Persistent Index: If this is a PK table, this is almost certainly the fix.
3. Reduce Buckets: If this table is small (under 100GB), ensure it doesn't have hundreds of buckets. Aim for ~1GB to 10GB per bucket.
References
• administration/management/monitoring/metrics-shared-data.md
• faq/shared_data_faq.md
• knowledge/admin_and_operation/shared_data_compaction.md