darshit.jain
08/25/2026, 6:59 AMstarrocks-mas-fe-0/1/2), CN nodes, no BE, FE Proxy disabled
• FE JVM: JDK 17, ZGC, -Xmx18g, container limit 26 GB, 8 CPU (6 available)
Symptom
All 3 FE pods restart every 2–8 minutes, continuously, for 29+ hours (577 restart markers in fe.out). Killed by liveness/readiness probe failure. CrashLoopBackOff gaps of ~5 min between some restarts.
GC analysis
• No OutOfMemoryError in any file — JVM never actually OOMs
• Live set plateaus at ~12 GB every run and stays flat (no leak, no unbounded growth)
• Heap therefore sits at 65–70% occupancy continuously
• GC Workers: 2 (dynamic) — appears to be the bottleneck
• *Allocation stalls up to 8.7 seconds*; 559 stalls in a single 5-minute run
• GC pause times are fine (max 0.028 ms) — the problem is stalls, not pauses
• Top stalling threads: thrift-server-pool (292 in one run), nioEventLoopGroup-6, star mgr replayer, replayer, star_os_checkpoint_worker
Conclusion: probes time out during 8s allocation stalls → kubelet kills pod.
Root cause candidate — star_os checkpoint never advances
From `fe.log`:
checkpoint imageJournalId 1086422, logJournalId 1086422 (global_state — current, OK)
checkpoint imageJournalId 5369484, logJournalId 9853250 (star_os — 4,483,766 behind)
StarManager.loadMeta():1319 end load star manager meta data at 08-15 02:26:18, replay journal id 5369484.
Last StarManager image is 10 days old. imageJournalId stayed pinned at 5369484 across every observed run.
Why checkpoint fails
1. Checkpoint worker unreachable:
CheckpointController.doCheckpoint():370 call doCheckpoint failed for node: starrocks-mas-fe-2..._9010_1784220843345
ThriftConnectionPool.reopen():108 reopen error → java.net.ConnectException: Connection refused
CheckpointController.pushImage():425 Exception when pushing image file. url = <http://starrocks-mas-fe-2|http://starrocks-mas-fe-2>...:8030/put?version=1085421&...&for_global_state=true&image_format_version=v2
HeartbeatMgr: get bad heartbeat response: type: FRONTEND, status: BAD, msg: Connection refused, replayedJournalId: 0
(fe-2 is itself crash-looping, so it can never serve as checkpoint worker → self-reinforcing loop)
2. Object storage rejecting writes — 635 occurrences, 103 distinct objects, continuous:
[Internal error: starlet err [RequestID=][StatusCode=403]Put object
<s3://bfsi-prd-dp-starrocks/d5a1d4e1-10da-4534-a69f-42d7a58e9992/db10001/9152040/9152042/SCHEMA_00000000008BA629|s3://bfsi-prd-dp-starrocks/d5a1d4e1-10da-4534-a69f-42d7a58e9992/db10001/9152040/9152042/SCHEMA_00000000008BA629>
error: Access denied.]
DdlException: fail to create tablet: 10016: [... StatusCode=403 ... Access denied.]
IllegalStateException: The table is not ready: task_run_history
Questions
1. Is the 4.48M-entry star_os journal backlog the reason the FE working set is ~12 GB? Will the resident metadata shrink once the checkpoint advances?
2. What is the correct recovery order when the checkpoint worker FE is itself crash-looping? Is there a way to force checkpoint on the leader, or pin the checkpoint worker to a specific FE?
3. Recommended ConcGCThreads / ParallelGCThreads and -Xmx-to-container-limit ratio for a shared-data FE with a ~12 GB live set? Is GC Workers: 2 on 6 CPUs expected, or is something misconfigured?
4. Recommended FE liveness/readiness probe settings so multi-second GC stalls don't trigger kills during recovery?
5. Does the star_os / StarManager image get written to object storage (i.e. would the 403 directly block it), or only to local meta/? Trying to confirm whether fixing S3 write perms alone unblocks the checkpoint.
6. Any fe.conf tuning to make the checkpoint trigger more aggressively so this backlog can't rebuild (e.g. checkpoint_interval_second, journal retention)?
Cluster: SHOW FRONTENDS shows leader flapping between fe-1 and fe-2; replayedJournalId: 0 on the dead ones.Rocky
08/25/2026, 7:24 AM403 Access denied on SCHEMA_... files means the FE cannot finalize metadata changes. The checkpoint will likely continue to fail until the FE has s3:PutObject permissions.
2. Force Checkpoint on Leader: By default, the Leader delegates checkpointing to a Follower to save resources. Since your Followers are crash-looping, the Leader is stuck.
* Set checkpoint_only_on_leader = true in fe.conf (or via ADMIN SET FRONTEND CONFIG).
* This forces the Leader to perform the checkpoint itself, bypassing the need to connect to the crashing Followers via Thrift.
3. GC & JVM Tuning
Your "GC Workers: 2" on 6 CPUs is quite low for a heap with heavy allocation churn during metadata replay. ZGC is "stalling" because it cannot clear space as fast as the replayer threads are allocating it.
* Threads: Manually set -XX:ConcGCThreads=4 (or at least 50% of available cores) to give ZGC more "muscle" during this recovery phase.
* Heap Ratio: 18GB Xmx in a 26GB container is a ~70% ratio. This is generally safe for StarRocks, but during a massive replay, the overhead of ZGC and off-heap metadata (Starlet/BDB) might be pushing the limits. If possible, temporarily increase the container limit to 32GB to provide breathing room.
4. Kubernetes Probe Recommendations
The 8.7s allocation stalls are triggering the liveness probe and killing the process just as it’s making progress.
* Increase `failureThreshold`: Set it to at least 15 or 20 with a periodSeconds of 10.
* Use `startupProbe`: Use a dedicated startup probe with a very long timeout (e.g., 30 minutes) to allow the 4.4M journals to replay fully without the Liveness probe being active.
* Liveness Probe: Should be more relaxed. A 30-60 second window of "unresponsiveness" is common during heavy FE metadata maintenance.
5. Metadata Storage (S3 vs. Local)
* Global State: The global_state image is stored in your local meta/ directory and synchronized between FEs via the HTTP put you saw in the logs.
* StarManager/star_os: In shared-data mode, while the journals are local, the underlying "tablets" and "schema" pointers managed by Starlet/StarManager involve S3. Your logs show [StatusCode=403] Put object ... SCHEMA_000.... This indicates that star_os is attempting to write metadata or state files to S3. If S3 is 403, star_os cannot commit its checkpoint. Fixing the S3 policy is a hard prerequisite.
6. fe.conf Tuning for Recovery
To clear the backlog and prevent it from recurring:
* checkpoint_max_journal_count = 50000 (Default): Ensure this isn't set higher.
* checkpoint_interval_second = 60: You can lower this temporarily to make the FE attempt checkpoints more frequently until it succeeds.Rocky
08/25/2026, 7:24 AMbdbje_cleaner_threads = 4: Increasing this helps the BDB (journaling) engine reclaim disk space and memory faster after the checkpoint finishes.
Summary Checklist
1. Update S3 IAM policy to allow PutObject and DeleteObject on the entire bucket.
2. Set checkpoint_only_on_leader = true in the Leader's fe.conf.
3. Add -XX:ConcGCThreads=4 to JAVA_OPTS.
4. Increase K8s failureThreshold for liveness/readiness probes to 20.
5. Restart FEs one by one. Monitor the fe.log specifically for end load star manager meta data and a new imageJournalId.
References
• administration/management/FE_configuration.md
• administration/management/BE_configuration.mddarshit.jain
08/25/2026, 8:27 AMcloud_native_storage_type property for gcs or we should use s3 only?Rocky
08/25/2026, 8:27 AMS3 type.
* cloud_native_storage_type: S3
* aws_s3_endpoint: <https://storage.googleapis.com>
* aws_s3_path: <s3://your-gcs-bucket-name/>... (GCS supports the s3:// scheme for compatibility).
* Credentials: Use HMAC keys (Access Key and Secret Key) generated in the GCS Console.
2. Native GCS Mode (StarRocks v3.5.1+)
Starting from v3.5.1, StarRocks supports a native Google Storage SDK.
* cloud_native_storage_type: GS
* Benefit: This may provide better performance or support for native GCP IAM roles (Service Accounts) without needing HMAC keys.
──────────
Why you are seeing the 403 error
Since your logs show [StatusCode=403] Put object <s3://bfsi-prd-dp-starrocks/...>, you are currently using the S3-compatible mode. The 403 error specifically means:
1. HMAC Key Permissions: The HMAC key used in fe.conf (or the Storage Volume) does not have storage.objects.create or storage.objects.delete permissions on that specific GCS bucket.
2. GCS Interoperability: Ensure "Interoperability" is enabled in your GCS settings and that the bucket's default project matches the HMAC key's project.
Recommendation:
If you are on a version earlier than 3.5.1, stay with cloud_native_storage_type = S3 but verify your GCS HMAC keys have Storage Object Admin permissions. If you change the storage type/path on an existing cluster, you risk making existing data read-only, so it is safer to fix the permissions for the current S3 protocol first.
References
• deployment/shared_data/gcs.md
• administration/management/FE_configuration.md
References
• deployment/shared_data/gcs.md
• administration/management/FE_configuration.mddarshit.jain
08/25/2026, 2:05 PMcheckpoint_only_on_leader = true is set and confirmed, yet selectWorker still chooses followers for star_os. Is this expected in 4.0.11? Is there a separate knob for star_os worker selection?
• heapUsedPercent is 0.90–0.9998 on all three FEs, and every checkpoint attempt kills its worker with "FE is dead". Is there a way to checkpoint incrementally, or a documented recovery path for a star_os backlog this large that doesn't require a heap big enough to hold the whole thing?Rocky
08/25/2026, 2:06 PMstar_os / StarManager specific behavior in your v4.0.11 environment:
1. star_os Worker Selection vs. checkpoint_only_on_leader
It is expected behavior that checkpoint_only_on_leader = true does not currently force the star_os (StarManager) checkpoint to the leader.
While that flag centralizes the general FE metadata checkpoint (BDBJE/GlobalState), the star_os module (StarManager) utilizes its own internal selectWorker logic. It often prioritizes followers to minimize performance impact on the leader's primary query-coordination tasks. In versions up to 4.0.x, there is no separate dedicated knob (like starmgr_checkpoint_only_on_leader) to force this specific task to the leader.
2. Recovery Path for a 4.48M Journal Backlog
There is no "incremental" checkpoint mechanism for star_os that bypasses memory. The worker must replay all 4.48M journals into memory to construct a consistent state before writing the new image. With a 12GB live set and 18GB heap (90%+ usage), the worker is virtually guaranteed to trigger a "Death Spiral":
1. Worker starts StarManager.loadMeta().
2. Heap occupancy hits 95%+, triggering ZGC allocation stalls (your 8s stalls).
3. K8s probes fail due to the stall; Pod is killed.
4. Checkpoint fails; the backlog remains.
Recommended Recovery Strategy:
* Temporary Heap Expansion (Required): You cannot recover a 12GB live set + 4.48M replay overhead in an 18GB heap. Temporarily increase -Xmx to 32GB (and pod limit to 40GB+) just for the recovery window. Once a successful image is created and journals are purged, the live set will shrink, and you can revert to 18GB.
* Fix S3 Permissions: The 403 Access Denied on SCHEMA_... objects is likely a hard blocker for the star_os checkpoint completion. If the worker cannot write the resulting metadata state to S3, the checkpoint will never "advance" even if the heap is sufficient.
* Startup Probe (K8s): Implement a startupProbe with failureThreshold: 60 and periodSeconds: 10. This gives the FE 10 minutes to replay the 4.4M journals without the Liveness probe killing it.
* Manual Trigger: Once the leader has finished replaying (look for end load star manager meta data in fe.log), execute:
sql
ALTER SYSTEM CREATE IMAGE;
While this primarily targets the GlobalState, it often triggers secondary maintenance tasks.
3. StarManager Specific Configs
If you are on 4.0.11, you can tune these to reduce pressure during recovery:
* starmgr_grpc_server_max_worker_threads: (Default 1024). During massive replays, you may see high thread contention. Reducing this temporarily to 256 can reduce context-switching overhead on your 6-8 CPU nodes.
* star_mgr_meta_sync_interval_sec: (Default 600). Increasing this to 3600 (1 hour) can prevent the leader from trying to sync with followers while they are still in a crash loop, reducing RPC noise.
Summary: The backlog is too large for your current heap. Fix the S3 permissions, double the heap memory temporarily, and use a K8s startup probe to let the replay finish. The resident metadata will shrink significantly once that checkpoint finally clears.
References
• administration/management/FE_configuration.md
• administration/Meta_recovery.md
• sql-reference/sql-statements/cluster-management/nodes_processes/ALTER_SYSTEM.md
References
• administration/management/FE_configuration.md
• deployment/deploy_manually.mddarshit.jain
08/25/2026, 2:08 PM-XX:ConcGCThreads=4 to JAVA_OPTS in fe.conf (confirmed present in the ConfigMap). FE processes started after the change still log:
CPUs: 8 total, 6 available
GC Workers: 2 (dynamic)
Full JAVA_OPTS: -Dlog4j2.formatMsgNoLookups=true -Xmx18g -Xms18g -XX:+UseZGC -XX:ConcGCThreads=4 -XX:+AlwaysPreTouch -XX:-ZUncommit -Xlog:gc*:...
JDK 17.0.19, StarRocks 4.0.11.
Is ConcGCThreads the correct knob for ZGC worker count in this JVM, or does the (dynamic) sizing override it? We were seeing 248–2682 allocation stalls per FE lifetime with stalls up to 8.7sRocky
08/25/2026, 2:09 PMConcGCThreads=4 results in 2 (dynamic)
In JDK 17+, ZGC ignores a static thread count by default and instead uses the flag -XX:+UseDynamicNumberOfGCThreads (enabled by default).
* The Log: GC Workers: 2 (dynamic) means the JVM has re-evaluated its workload and decided that 2 threads are currently sufficient to keep up with allocation without "stealing" too much CPU from your FE application.
* The Limit: Your -XX:ConcGCThreads=4 acts as the upper bound for this dynamic selection. The JVM will scale between 1 and 4 threads as it sees fit.
* The CPU Heuristic: By default, ZGC targets a very conservative CPU usage (~12.5% of available cores). On an 8-core machine, the default would normally be 1 thread. The fact that it scaled to 2 shows it knows it's under pressure, but it hasn't deemed 4 necessary yet—even though your application is actually stalling.
2. How to fix the Allocation Stalls
To mitigate the 8.7s stalls, you need to make ZGC more aggressive and potentially "static" during this high-load recovery phase:
* Force a Static Thread Count: Disable dynamic scaling to ensure ZGC always has 4 threads available for marking and relocation.
bash
-XX:-UseDynamicNumberOfGCThreads -XX:ConcGCThreads=4
* Increase Spike Tolerance: ZGC uses a heuristic to predict future allocation rates. During a massive journal replay, the allocation is extremely bursty. Increase the tolerance (default is 2.0) to make GC start earlier:
bash
-XX:ZAllocationSpikeTolerance=5.0
* Set a Soft Max Heap: Tell ZGC to get aggressive before it hits the 18GB limit. If your Xmx is 18GB, setting a SoftMax at 14-15GB can prevent the "panic" state that leads to long stalls:
bash
-XX:SoftMaxHeapSize=15g
3. Recommended JAVA_OPTS for your 8-core/18GB FE
Given your specific environment (shared-data mode, 4.4M journal backlog), update your fe.conf to:
bash
JAVA_OPTS="-Xmx18g -Xms18g -XX:+UseZGC \
-XX:ConcGCThreads=4 \
-XX:-UseDynamicNumberOfGCThreads \
-XX:ZAllocationSpikeTolerance=5.0 \
-XX:SoftMaxHeapSize=15g \
-XX:+AlwaysPreTouch -XX:-ZUncommit"
Summary of the "6 available" CPU count
The JVM log CPUs: 8 total, 6 available usually indicates that Kubernetes CPU limits or requests (specifically CFS quotas) are being detected. Because the JVM thinks it only has 6 effective cores to work with, it is being even more conservative with GC threads to avoid starving the thrift-server-pool and replayer threads you saw in the stall logs. Forcing ConcGCThreads=4 and disabling dynamic scaling is the correct move here to prioritize memory health over slight CPU contention.
References
• administration/management/FE_configuration.md
• administration/Meta_recovery.md
• deployment/deploy_manually.mddarshit.jain
08/25/2026, 2:24 PM2026-08-25 18:10:50.935+05:30 WARN (thrift-server-pool-2651|7168) [LeaderImpl.finishTask():198] finish task reports bad. request: TFinishTaskRequest(backend:TBackend(host:starrocks-mas-cn-2.starrocks-mas-cn-search.starrocks.svc.cluster.local, be_port:9060, http_port:8040), task_type:CREATE, signature:9216342, task_status:TStatus(status_code:RUNTIME_ERROR, error_msgs:[Internal error: starlet err [RequestID=][StatusCode=403]Put object <s3://bfsi-prd-dp-starrocks/d5a1d4e1-10da-4534-a69f-42d7a58e9992/db10001/9216327/9216341/SCHEMA_00000000008CA149> error: Access denied.]), report_version:17842209360000)
but the permissions on the pod are granted correctly. what can be the issue?Rocky
08/25/2026, 2:25 PM403 Access Denied error during a Put object operation on a SCHEMA_ file indicates that while the pod might have an identity, the Compute Node (CN) or Backend (BE) does not have sufficient permissions to write to that specific GCS bucket path.
Even if you have granted permissions to the pod, here are the most likely reasons for this specific StarRocks error:
1. Missing aws_s3_use_instance_profile
If you are using GKE Workload Identity (granting permissions via a Kubernetes Service Account bound to a GCP Service Account), StarRocks will not automatically "pick up" the pod's identity for its internal storage engine (starlet) unless explicitly told to do so.
* Fix: Ensure you have the following in your fe.conf (and `cn.conf`/`be.conf` if configured separately):
properties
aws_s3_use_instance_profile = true
Without this, StarRocks may default to an "anonymous" request or look for HMAC keys that aren't provided, resulting in a 403.
2. BE/CN Pods vs. FE Pods
The error log you provided comes from a Compute Node (starrocks-mas-cn-2...).
* Issue: Users often apply the Service Account annotation and GCP IAM roles to the FE pods but forget to apply the exact same configuration to the CN/BE pods.
* Check: Ensure your CN/BE Deployment or StatefulSet has:
1. The serviceAccountName matching the one bound to GCP.
2. The annotation <http://iam.gke.io/gcp-service-account|iam.gke.io/gcp-service-account>: <your-gsa>@<project>.<http://iam.gserviceaccount.com|iam.gserviceaccount.com>.
3. Insufficient IAM Roles for Metadata
StarRocks shared-data mode doesn't just read data; it must manage its own metadata (SCHEMA_ and segment files).
* Requirement: The GCP Service Account needs the Storage Object Admin role (or at minimum Storage Object Creator and Storage Object Viewer) on the bucket.
* Common Trap: If your bucket has Uniform bucket-level access enabled, ensure you haven't accidentally limited the Service Account's permissions to a specific sub-folder that doesn't match the aws_s3_path prefix.
4. GCS Interoperability (If using HMAC Keys)
If you are not using Workload Identity but are using HMAC keys (aws_s3_access_key):
* Go to GCS Settings > Interoperability.
* Ensure the Default Project for interoperability matches the project where the bucket resides.
* If the HMAC key is from a different project than the bucket, GCS will return a 403 unless the key's project has been granted explicit permission on the bucket.
5. "Uniform bucket-level access" vs ACLs
If your GCS bucket has ACLs enabled (Access Control Lists), a pod writing a file might not be granting "owner" permissions to the bucket owner. However, StarRocks generally works best with Uniform bucket-level access enabled and IAM roles. If you must use ACLs, ensure the IAM principal has "Owner" or "Legacy Bucket Writer" permissions.
Recommendation:
1. Verify aws_s3_use_instance_profile = true is set.
2. Check that the CN pods have the correct Service Account.
3. Test the permission from inside a CN pod using the gcloud or gsutil CLI:
bash
# Run this inside the starrocks-mas-cn-2 pod
gsutil cp some_local_file <gs://bfsi-prd-dp-starrocks/test_write>
If this fails, the issue is with the GCP/GKE identity binding, not StarRocks.
References
• deployment/shared_data/gcs.md
• integrations/authenticate_to_gcs.md
• administration/management/FE_configuration.md
References
• deployment/shared_data/gcs.md
• integrations/authenticate_to_gcs.md
• administration/management/FE_configuration.mdRocky
08/25/2026, 2:25 PMdarshit.jain
08/25/2026, 2:41 PMrun_mode = shared_data and enable_load_volume_from_conf = true, FE auto-created an S3-type builtin_storage_volume. A GS-type volume is default. Internal tables (_statistics_, db10001) appear to still use the builtin S3 volume and get 403 Put object. How do we redirect internal/system table creation to the default GS volume? Can builtin_storage_volume be disabled or deleted safely?
2. Is aws_s3_use_instance_profile = true supported against <http://storage.googleapis.com|storage.googleapis.com>, or does S3 interop require HMAC keys?Rocky
08/25/2026, 2:42 PMshared_data mode, the behavior of internal and system tables (like _statistics_) and the builtin_storage_volume is as follows:
* How to "Redirect": You cannot directly "move" existing data from one volume to another with a single command. However, internal system tables and the default_catalog always follow the Default Storage Volume. To redirect future internal data:
1. Create your desired GS-type volume:
sql
CREATE STORAGE VOLUME my_gs_volume
TYPE = GS
LOCATIONS = ("<gs://your-bucket/path/>")
PROPERTIES ("enabled" = "true", ...);
2. Set it as the default:
sql
SET my_gs_volume AS DEFAULT STORAGE VOLUME;
3. Note on Existing Tables: For user tables (like your db10001), the storage_volume property is often inherited at creation. Changing the default volume only affects newly created tables or partitions. To change an existing table's volume, you must:
sql
ALTER TABLE <table_name> SET ("storage_volume" = "my_gs_volume");
Warning: This only affects new data. Existing data remains on the old volume unless you re-insert/overwrite it.
* Disabling/Deleting `builtin_storage_volume`:
* Cannot be dropped: The documentation explicitly states that the builtin_storage_volume cannot be dropped.
* Can be disabled: You can set "enabled" = "false" via ALTER STORAGE VOLUME builtin_storage_volume SET ("enabled" = "false"), but only after you have designated another volume as the default.
* Best Practice: Do not try to delete it. Simply set your manual GS volume as the default and disable the built-in one if you wish to prevent accidental use.
──────────
2. aws_s3_use_instance_profile vs. GCS
No, aws_s3_use_instance_profile = true is not supported for Google Cloud Storage (GCS) when using the S3 endpoint (<http://storage.googleapis.com|storage.googleapis.com>).
* S3 Interoperability: When you use TYPE = S3 against GCS, StarRocks uses the AWS C++ SDK. That SDK's instance_profile logic is hardcoded to look for the AWS Instance Metadata Service (IMDS) at 169.254.169.254. While GCP has a similar service, the response format and authentication headers (Identity Tokens vs. IAM Roles) are incompatible.
* The HMAC Requirement: If you must use S3-interoperability (URIs starting with s3:// pointing to GCS), you must use HMAC keys (aws_s3_access_key and aws_s3_secret_key).
* The Recommended Path (Native GS): Since you are on v4.0.11, you should avoid S3-interop and use the native GS volume type. This allows you to use GKE Workload Identity or Compute Engine Service Accounts without HMAC keys:
sql
CREATE STORAGE VOLUME gcs_native
TYPE = GS
LOCATIONS = ("<gs://your-bucket/>")
PROPERTIES (
"gcp.gcs.use_compute_engine_service_account" = "true",
"enabled" = "true"
);
This native integration uses the GCS-specific SDK which correctly handles Google's identity metadata.
Summary: Your 403 Put object error is likely happening because the S3-interop layer is trying to use an AWS-specific identity method that doesn't work on GCP. Switch to TYPE = GS and set it as your default volume to resolve the permission issues for system tables.
References
• sql-reference/sql-statements/cluster-management/storage_volume/SET_DEFAULT_STORAGE_VOLUME.md
• sql-reference/sql-statements/cluster-management/storage_volume/CREATE_STORAGE_VOLUME.md
• deployment/shared_data/gcs.mdRocky
08/25/2026, 2:42 PMdarshit.jain
08/25/2026, 3:12 PMimageJournalId 5369484 vs logJournalId 9918980, checkpoint failing with OutOfMemoryError on -Xmx18g.
What is the supported procedure to recover from the existing image and discard the un-checkpointed star_os journal, on a 3-FE shared-data cluster running the Kubernetes operator? Do all three FEs need meta cleared, or only the leader?Rocky
08/25/2026, 3:13 PMOutOfMemoryError occurs because the FE is attempting to replay nearly 4.5 million journal entries (from 5,369,484 to 9,918,980) into memory during startup. Since you confirmed no user tables or metadata changes have occurred since the last image, discarding these journals is the most efficient way to restore service.
Supported Procedure
1. Prepare the Environment
* Scale Down: Set the FE replicas to 0 in your StarRocksCluster CRD to stop all FE processes and prevent the operator from restarting them during maintenance.
bash
kubectl patch starrockscluster <cluster-name> --type merge -p '{"spec":{"starRocksFeSpec":{"replicas":0}}}'
* Backup: (Highly Recommended) Back up the current meta_dir of at least the node you intend to make the leader.
2. Clean the Leader Metadata (FE-0)
You must clear the BDBJE logs (the journal) but keep the image file.
* Access the persistent volume of the first FE (typically starrocks-fe-0). You can do this by launching a temporary "maintenance" pod that mounts the same PVC.
* Navigate to the meta/ directory.
* Delete the bdb/ directory: This directory contains the un-checkpointed journals that are causing the OOM.
bash
rm -rf /opt/starrocks/fe/meta/bdb/*
* Verify the image/ directory: Ensure the file image.5369484 (and its associated .checksum) is present. Do not delete this directory.
3. Clear Follower Metadata (FE-1, FE-2)
To ensure no old journals conflict with the new leader, the simplest way is to delete the PVCs for the other two FE pods. The operator will recreate them with empty storage, and they will automatically sync the image and new journals from the leader.
bash
kubectl delete pvc <pvc-name-fe-1> <pvc-name-fe-2>
4. Reconfigure and Start the Leader
* Set Recovery Flag: Update your FE configuration (via the ConfigMap referenced in your CRD) to include:
properties
bdbje_reset_election_group = true
* Scale to 1: Scale the FE replicas to 1.
bash
kubectl patch starrockscluster <cluster-name> --type merge -p '{"spec":{"starRocksFeSpec":{"replicas":1}}}'
* Monitor: Check the fe.log of fe-0. It should load the image and start as LEADER. Because the bdb/ directory was empty, it will start a fresh journal sequence beginning at the image's ID.
5. Stabilize and Re-scale
* Create New Image: Once the leader is healthy, force a checkpoint to consolidate the state:
sql
-- Connect to the leader FE via MySQL client
ALTER SYSTEM CREATE IMAGE;
* Scale to 3: Re-scale the FE replicas to 3. The new FE-1 and FE-2 pods will start, see that they have no metadata, and perform a full image sync from FE-0.
bash
kubectl patch starrockscluster <cluster-name> --type merge -p '{"spec":{"starRocksFeSpec":{"replicas":3}}}'
* Cleanup Config: Once all 3 FEs are Alive (check SHOW FRONTENDS;), remove bdbje_reset_election_group = true from your configuration to prevent accidental election resets in the future.
Summary of FE Requirements
* Do all three FEs need meta cleared? Yes. If you only clear the leader, the followers may still possess the "future" journals and cause a conflict or attempt to become leader with the bad journal data.
* Leader vs. Follower: Only the newly designated leader needs to keep the image/ directory. The followers should have their entire meta/ directory cleared (or PVCs deleted) so they can re-sync from the leader's clean state.
Important NotesRocky
08/25/2026, 3:13 PMstar_os (StarMgr) journals are stored within the same BDBJE environment in the bdb/ directory. Deleting bdb/ handles both the Global State and StarMgr journals simultaneously.
* Data Loss: Any metadata changes (e.g., routine load offsets, user permissions) created between journal 5,369,484 and 9,918,980 will be lost. Since you confirmed no tables were created, the impact should be minimal (mostly offset progress for routine loads).
References
• deployment/shared_data/hdfs.md
• administration/Meta_recovery.md
• quick_start/shared-data.md
• quick_start/routine-load.mddarshit.jain
08/25/2026, 5:39 PMmin_graceful_exit_time_second = 25. The preStop hook (fe_prestop.sh) failed, meaning fe-0 was killed ungracefully. That can leave BDBJE mid-write , it may have contributed to the checkpoint corruption. Is that possible?Rocky
08/25/2026, 5:40 PMSIGKILL on BDBJE
StarRocks uses Berkeley DB Java Edition (BDBJE) for its metadata journal. While BDBJE is transactional and designed to be robust, an ungraceful exit (like a SIGKILL after a failed preStop hook) can lead to several issues:
* Incomplete Writes: If the FE was killed while writing a new journal entry or during the middle of a BDBJE "cleaner" cycle, the log files can be left in a state that requires a heavy "recovery" scan upon restart.
* Journal Truncation: BDBJE may find the last log file partially written and be forced to truncate it. In a multi-FE cluster, this can lead to the RollbackException or InsufficientLogException mentioned in the logs if the followers are out of sync.
2. Why the Checkpoint Failed (The OOM Connection)
The gap between your imageJournalId (5M) and logJournalId (9.9M) represents 4.5 million un-checkpointed entries.
* Already Broken: The checkpointing process was likely failing long before the ungraceful shutdown occurred. In StarRocks, if the BDBJE journal grows too large because checkpoints aren't succeeding, the FE will eventually run out of memory trying to load/replay those journals on startup.
* The Vicious Cycle: If a checkpoint fails (often due to memory pressure or the 403 S3/GCS errors you saw earlier), the BDBJE log files are not deleted. Upon an ungraceful restart, the FE must replay every single entry since the last image (5.3M) into memory. Replaying 4.5 million entries into an 18GB heap is frequently what triggers the OutOfMemoryError you are seeing.
3. The preStop Hook and min_graceful_exit_time_second
The fe_prestop.sh script is critical because it tells the FE to:
1. Stop accepting new connections.
2. Wait for in-flight queries to finish.
3. Perform a clean closure of the BDBJE environment.
4. If it is the Leader, it tries to step down so another FE can take over.
If this hook failed or timed out (K8s terminationGracePeriod is usually 30s by default), the FE process was simply killed. This prevents the "Clean Shutdown" flag from being written to the BDBJE logs. On the next start, the FE sees it didn't shut down cleanly and initiates a full recovery scan, which is significantly more memory-intensive than a clean start.
Is min_graceful_exit_time_second the culprit?
While min_graceful_exit_time_second (which ensures the FE stays alive for a minimum duration to allow Load Balancers to react) helps with availability, it doesn't solve a failing preStop script. If the preStop script itself is failing (due to permissions, path issues, or the FE being already unresponsive/OOM), the FE will always end up being killed ungracefully.
Recommendation
1. Recovery: Follow the procedure provided previously to discard the un-checkpointed journals (clear bdb/ but keep image/). There is no way to replay 4.5M entries with your current heap size.
2. Fix Permissions: The 403 Put object error is the "root" of the checkpoint failure. The FE cannot create a new image file if it cannot write to the storage volume. Once you fix the GCS/S3 volume permissions, checkpoints will succeed again.
3. Increase Memory: For a journal gap this large, even if BDBJE weren't "corrupt," an 18GB heap is likely too small for the replay. Consider increasing the FE -Xmx if your metadata grows significantly.
4. Debug preStop: Check the kubectl describe pod events to see why fe_prestop.sh failed. Often it's because the FE was already in a "hanging" state due to the OOM or checkpoint block.
References
• administration/management/graceful_exit.mdRocky
08/25/2026, 5:40 PMdarshit.jain
08/25/2026, 5:55 PMimage/v2/ (global_state) was written today at 21:15 while image/starmgr/ has been frozen since Aug 15 — same filesystem, same process. So local image writes are working; the 403s were TableKeeper failing to create _statistics_ tablets on a misconfigured S3-interop volume (now disabled), which added journal churn but didn't block checkpointing.
The checkpoint failure is java.lang.OutOfMemoryError: Java heap space in star_os_checkpoint_controller with no storage error in the trace.
Also confirmed from GKE pod events: the trigger was liveness probe timeouts (timeoutSeconds: 5) against GC stalls up to 8.7s — isolated stalls at 2113/2146/22:55 recovered, then a sustained one at 23:31 caused the first kill and the cascade. We're setting livenessProbeFailureSeconds: 600 permanently.
Your SIGKILL/BDBJE point is well taken — does the failed preStop mean the recovery scan on each restart is meaningfully heavier, and is there anything in the recovery procedure that should account for an unclean BDBJE state?Rocky
08/25/2026, 5:55 PMstarmgr image vs. the global_state image confirms the root cause. In StarRocks shared-data mode, the FE maintains two distinct metadata sets: the standard StarRocks metadata (global_state) and the StarOS metadata (starmgr), which tracks things like object storage mappings and tablet-to-CN placements.
1. Is the recovery scan "meaningfully heavier" after a SIGKILL?
Yes, significantly.
When BDBJE is closed gracefully, it writes a "checkpoint" entry to the log and flushes all buffers. Upon restart, it simply reads from the last checkpoint.
After a `SIGKILL`:
* Log Verification: BDBJE must perform a "Recovery Scan." It must read every log file from the last successful BDBJE checkpoint to the end of the log to verify checksums and rebuild the in-memory mapping of database IDs.
* Memory Pressure: If you have 4.5 million entries (the gap between journal 5M and 9.9M), the FE will attempt to load the metadata into the heap while simultaneously replaying these journals. Since your starmgr image is from Aug 15 (entry ~5M), the star_os_checkpoint_controller is likely failing because it's trying to reconstruct the entire StarOS state for the last 10 days in memory just to begin the checkpoint.
* CPU/IO Spike: The combination of an unclean BDBJE state and a massive journal backlog creates a "startup storm" that usually triggers the liveness probe again before the FE can finish the scan—leading to the "cascade" you observed.
2. Does the recovery procedure need to account for the unclean state?
The procedure provided (clearing bdb/ while keeping image/) is the correct way to handle an unclean state. By deleting the bdb/ directory, you are effectively telling the FE: "Ignore the corrupted/unclean logs entirely; start a fresh journal stream using the last valid snapshot (the image files)."
Specific things to note for your starmgr discrepancy:
* Image Disparity: Since your global_state image is current but your starmgr image is from Aug 15, clearing the journals will revert your StarOS state to Aug 15.
* The "Zero Table" Safety Net: Because you confirmed no new tables/partitions were created since Aug 15, the StarOS state should be relatively static. Reverting to the Aug 15 starmgr image is safe; the only thing you might "lose" is internal housekeeping (like exactly which CN was assigned which tablet for cache-warmup purposes), which StarRocks will naturally re-calculate.
* Force a StarMgr Checkpoint: After you get the cluster back up with one FE and bdbje_reset_election_group = true, run ALTER SYSTEM CREATE IMAGE;. This should force both metadata sets to write a fresh image, finally updating the starmgr image.
3. Adjustments to your Liveness/PreStop Logic
* Liveness Probe: Your plan to set livenessProbeFailureSeconds: 600 (10 minutes) is wise. During metadata recovery or large journal replays, the JVM can be entirely "frozen" by GC for 30–60 seconds. A 5-second timeout is almost guaranteed to cause a kill during recovery.
* PreStop Failure: The fe_prestop.sh likely failed because the FE was already in an OOM/Long-GC state and couldn't respond to the <http://localhost:8030/api/bootstrap> (or similar) check used to initiate a graceful exit.
* Heap Recommendation: With a 4.5M journal gap, 18GB is very tight. If the recovery (after clearing BDB) still feels sluggish, temporarily bump the FE to 24GB or 32GB until a fresh checkpoint is successfully written to the image/ directory.
Final Sanity Check on the Procedure:
1. Scale to 0 (Wait for pods to vanish).
2. On FE-0 PVC: Delete meta/bdb/*. Leave meta/image/ exactly as is.
3. On FE-1/FE-2 PVCs: Delete the entire meta/ directory (ensure they start empty).
4. Update ConfigMap: Add bdbje_reset_election_group = true.
5. Scale to 1 (Wait for FE-0 to become LEADER).
6. Force Checkpoint: ALTER SYSTEM CREATE IMAGE;.Rocky
08/25/2026, 5:55 PMmeta/image/starmgr/ now has a timestamp from today.
8. Scale to 3.
Once the cluster is stable, remove the bdbje_reset_election_group flag so that a future reboot doesn't accidentally cause a split-brain if the FE fails to see its peers.
References
• administration/Meta_recovery.mddarshit.jain
08/26/2026, 2:23 AMSHOW PROC '/statistic'). Yet the star_os journal reached 4.5M entries and FE live set hit ~15 GB on an 18 GB heap.
That's ~118,000 journal entries per tablet. What generates star_os journal entries at that rate on a cluster this small with all routine loads paused since Aug 13?
We found TableKeeper retrying _statistics_ tablet creation every 30–60s (7,529 failures, _statistics_ still shows TableNum: 0) against a misconfigured S3-interop volume, plus StarMgrMetaSyncer.cleanOneGroup() failing with GRPC:DEADLINE_EXCEEDED on shard group deletion. Could either loop account for this volume? How to confirm this?Rocky
08/26/2026, 2:23 AMTableKeeper loop and StarMgrMetaSyncer failures is exactly where the "metadata storm" is coming from.
1. The TableKeeper loop and Shard Proliferation
In shared-data mode, StarRocks does not just create a "table" in the traditional sense. It orchestrates StarOS Shards and Shard Groups.
* Multiplier Effect: Even if the _statistics_ table is small (e.g., 10 buckets), each creation attempt involves:
1. Creating a Shard Group in StarMgr.
2. Creating 10 individual Shards (one for each tablet/bucket).
3. Persisting the mapping of Shard → Object Storage path.
* Journal Churn: If TableKeeper retried 7,529 times, and each attempt partially created these StarOS entities before failing on the S3 Put object call, you generated at least 80,000 to 150,000 StarOS journal entries just from the creation attempts.
2. The StarMgrMetaSyncer "Journal Storm"
The real culprit for the 4.5M entries is likely the cleanup logic triggered by these failures.
* Orphaned Shards: When a table creation fails halfway, StarOS leaves behind "orphaned" shards and shard groups that have no owner in the Global State.
* The Syncer Loop: StarMgrMetaSyncer runs a background task (often every few seconds or minutes) to identify and delete these orphans.
* DEADLINE_EXCEEDED & Retries: If cleanOneGroup() is failing with a gRPC timeout, it means the StarOS metadata service is struggling to process the deletion of the thousands of "ghost" shards created by your 7,529 retries.
* Failure Persistence: In some versions of StarRocks, if a cleanup task fails, it logs the failure or state transition to the journal. If this syncer was running frequently (e.g., trying to clean 7,000+ groups) and each "attempt" or "timeout" resulted in a journal record, the journal can balloon into the millions very quickly.
3. Why the FE Live Set is 15 GB
The OutOfMemoryError isn't just about the BDB logs on disk; it's about the in-memory representation of StarOS metadata.
* StarRocks maintains a StarMgr object in the FE heap that maps every Shard to its location.
* If the cleanup (cleanOneGroup) is failing, these 7,500+ failed "tables" worth of shards (potentially 75,000+ shards) are sitting in the FE memory as "Dangling" or "To-be-cleaned" metadata.
* Replaying a journal with 4.5 million entries requires the FE to rebuild this entire graph of "created-then-deleted-then-failed-to-delete" shards in memory, which easily exhausts an 18 GB heap.
How to Confirm
Once you have performed the recovery (clearing bdb/ but keeping image/ as discussed previously), you can verify the state of the "ghost" metadata using these internal diagnostic paths:
1. Check Shard Count:
sql
-- Check how many shards StarOS thinks it has
SHOW PROC '/starmgr/shard_groups';
If this returns thousands of rows for a cluster that should only have ~40 tablets, you have confirmed the bloat.
2. Check StarMgr Journal Stats:
Search your fe.log for StarMgr journal. You will likely see that the StarOS/StarMgr journal sequence is moving significantly faster than the Global State journal sequence.
Permanent Fix
* Fix S3/GCS Credentials: (Already done, as you noted). This stops the TableKeeper from adding new "garbage" to the journal.
* Increase `starmgr_grpc_timeout_seconds`: If you continue to see DEADLINE_EXCEEDED during cleanup, increase this config (default is 5s) to 30s to allow the metadata syncer to finish its work without timing out.
* Scale FE Heap: For shared-data clusters, the FE memory requirement is proportional to the number of shards (including deleted/trash shards) rather than just active tablets. Given the churn, 18 GB is the bare minimum; 32 GB is recommended for stability during recovery.
ReferencesRocky
08/26/2026, 2:23 AMdarshit.jain
08/26/2026, 2:29 AMSHOW PROC '/starmgr/shard_groups';
not working for starrocks 4.1Rocky
08/26/2026, 2:30 AM/starmgr/shard_groups has indeed been moved or restricted.
To confirm the "Shard Group Storm" and the bloat from the failed TableKeeper retries in version 4.1, use the following paths:
1. The Correct SHOW PROC Paths for 4.1
In 4.1, StarOS metadata is typically found under the /staros or /lake hierarchy. Try these in order:
* Primary Path: SHOW PROC '/staros/shard_groups';
* Secondary Path: SHOW PROC '/lake/shards'; (This shows the actual tablet-to-object-storage mapping)
* Cluster Summary: SHOW PROC '/statistic'; (Check the TabletNum here. If it says 38 but the shard count from the commands above is in the thousands, you have confirmed the orphans).
2. Check the System Tables (Recommended for 4.1)
StarRocks 4.x has moved much of the internal metadata visibility into information_schema. This is often more reliable than `SHOW PROC`:
sql
-- Check for an abnormal number of shard groups
SELECT count(*) FROM information_schema.be_tablets;
-- Check for orphaned/dangling metadata if the table exists in your build
SELECT * FROM information_schema.lake_tablets;
3. Confirming the TableKeeper Loop
Since _statistics_ shows TableNum: 0 but you have 7,529 failures, the TableKeeper is likely stuck in a loop trying to initialize the system statistics database. Each cycle it:
1. Requests StarOS to create a Shard Group.
2. Tries to write the initial tablet metadata to S3/GCS.
3. Fails at the S3/GCS step (the 403 you saw).
4. Crucially, it might not be successfully "rolling back" the Shard Group creation in the BDBJE journal before retrying.
4. Why the FE is OOM despite the tiny cluster
Even with 38 "real" tablets, if the TableKeeper generated 7,000+ Shard Groups, and each Shard Group contains shards for the _statistics_ partitions, you likely have ~75,000 to 100,000 internal "ghost" shards registered in the FE memory.
* Replay Cost: Replaying 4.5 million journal entries isn't just "reading logs"—it's the FE process attempting to reconstruct the state of these 100k shards in the JVM Heap.
* GC Stalls: 18GB is plenty for 38 tablets, but it is not enough for an FE carrying the "ghost" metadata of thousands of failed table creations.
Steps to Clear the Bloat
1. Perform the BDB Clear: Follow the recovery (deleting meta/bdb/*). This is the only way to "forget" the 4.5M entries of churn.
2. Fix the Volume: Ensure the S3/GCS volume is accessible. If TableKeeper can finally succeed once, the loop will stop.
3. Disable Stats temporarily: If you cannot fix the volume yet, set enable_stats = false in fe.conf to stop TableKeeper from trying to create the _statistics_ table entirely.
4. Wait for `StarMgrMetaSyncer`: Once the cluster is up, the syncer will eventually (based on star_mgr_meta_sync_interval_sec) start cleaning up the old shard groups. In 4.1, you can speed this up by increasing the gRPC timeout if you see DEADLINE_EXCEEDED in the logs.
Reference:
* StarRocks 4.1 Release Notes - Metadata Management
* Shared-data FAQ - Tablet Metadata
References
• faq/shared_data_faq.md
• knowledge/admin_and_operation/shared_data_compaction.mddarshit.jain
08/26/2026, 2:54 AMRocky
08/26/2026, 2:55 AMmetadata_journal_skip_bad_journal_ids (For specific corruptions)
If the FE specifically crashes with an error like got interrupt exception or inconsistent exception when replay journal xxx, you can skip specific IDs:
* Variable: metadata_journal_skip_bad_journal_ids = xxx,yyy
* Use case: This is intended for individual "poison pill" entries. With 4.5 million entries, this is likely impractical unless only the very last few are corrupt.
2. metadata_ignore_unknown_operation_type
If the journal entries are from a newer/different version or contain types the FE doesn't recognize (common in misconfiguration or rollback scenarios):
* Variable: metadata_ignore_unknown_operation_type = true
* Effect: It allows the replayer to skip entries it doesn't understand rather than crashing.
3. metadata_enable_recovery_mode (The "Safety" Mode)
* Variable: metadata_enable_recovery_mode = true
* Effect: This puts the FE into a restricted mode that ignores many tablet-level consistency checks during replay. It is often used to get a cluster up so you can run ALTER SYSTEM CREATE IMAGE; and "checkpoint" your way out of a bad state.
* Constraint: You cannot perform any DDL/Write operations in this mode.
4. The "Manual Abandonment" (Recommended for your 4.5M Bloat)
Because your "corruption" is actually logic-driven bloat (7,500 loops of failed creations), the entries are likely syntactically valid BDBJE logs but functionally "garbage." The JVM is OOM-ing because it's trying to build a massive in-memory state representing those 4.5M operations.
There is no configuration variable that will tell the FE to "skip everything between journal ID 5M and 9.5M."
To truly abandon those entries, you must use the procedure discussed earlier:
1. Stop the FE.
2. Delete the meta/bdb/ directory.
3. Start with bdbje_reset_election_group = true.
By deleting the bdb/ folder, you are effectively forcing the FE to abandon all journal entries and start fresh from the last valid snapshot in the meta/image/ directory. Given that your image/ was updated at 21:15 today (for global_state), you will only lose the metadata changes that occurred between 21:15 and the crash—which, in your case, sounds like it was almost entirely the 403-error loop and statistics failures.
Summary of variables for your fe.conf during recovery:
properties
# Force the FE to ignore its peer list and start as a solo leader
bdbje_reset_election_group = true
# If the replay still hits specific "Unknown Type" errors due to 4.1 logic
metadata_ignore_unknown_operation_type = true
# Increase the timeout for the syncer to clean up the ghost shards
starmgr_grpc_timeout_seconds = 30
# Temporary heap boost to handle the initial state reconstruction
# Ensure your pod has the request/limit to back this up
# -Xmx24g or higher is recommended given the shard count
Note: After successfully starting and running ALTER SYSTEM CREATE IMAGE;, remember to remove bdbje_reset_election_group and metadata_enable_recovery_mode before adding the other FE nodes back.
References
• administration/Meta_recovery.mddarshit.jain
08/26/2026, 5:50 AMDbPrintLog shows only ~1M records matching your global_state journal (ReplayedJournalId ~1092900) rather than 9.9M, that tells you star_os journals live elsewhere, which is itself useful to know before you delete bdb/. Is this reasoning correct? or will it be present in bdbjeRocky
08/26/2026, 5:51 AMmeta/bdb/. This contains high-level metadata: databases, tables, users, and transactions. This is what you checked with DbPrintLog and found ~1M records.
* StarManager (StarOS) Journal: Often located in meta/staros/bdb/ (or a similar subdirectory under meta/). This contains the "shard-to-object" mapping, shard group metadata, and storage volume info. This is where your 4.5M to 9.9M entries are residing.
2. Confirming the Separation
The fact that DbPrintLog on your main BDB directory only shows 1M records while the system reports millions of star_os entries is the "smoking gun."
* Separate Sequences: As you saw in your SHOW PROC or snapshot views, there is an fe_journal_id and a starmgr_journal_id. They do not share the same sequence numbers.
* Independent Replay: When the FE starts, it launches two separate replay threads—one for the Global State and one for the StarManager.
3. Why this Matters for your Recovery
If you delete only meta/bdb/, you will reset your Global State (the 1M entries), but the FE might still OOM during restart because the StarManager replayer will still attempt to load the 4.5M bloated entries from the other directory.
To truly clear the "journal storm" and the 15GB heap usage, you must address both:
1. Stop the FE.
2. Locate the StarOS BDB directory: It is usually meta/staros/bdb. Check its size; if it matches the 4.5M entries bloat, that is your target.
3. Clear both if necessary:
* If you delete meta/bdb/, the Global State restarts from the last image.
* If you delete meta/staros/bdb/, the StarManager restarts from its last image.
_ _Note:* In StarRocks 4.x, StarOS often stores its own "images" (checkpoints) in meta/staros/image/.
4. The Danger of "In-Sync" Recovery
In Lake mode, the Global State and StarOS metadata must remain somewhat in sync.
* Scenario: If the Global State "knows" about a table but you delete the StarOS metadata (the shard info), the table becomes a "ghost" with no data locations.
* Your Case: Since your bloat was caused by failed creations (TableNum: 0), the Global State likely doesn't even know these tables exist. The "garbage" is trapped entirely in the StarOS journal.
Recommendation
1. Check for `meta/staros/bdb/`: Verify that this folder is the one containing the massive amount of BDB .jdb files.
2. Clear StarOS BDB if it's the culprit: If the 4.5M entries are there, you should treat it the same way as the FE recovery: delete the bdb/ files but keep the image/ files so StarOS can recover its state from the last valid checkpoint.
3. Restart with Recovery Mode: Use metadata_enable_recovery_mode = true in fe.conf to allow the system to come up without failing on the missing "ghost" shards.
Summary: Your reasoning is spot on. You found the 1M FE records, but the "Missing 9M" are in the StarManager's own dedicated storage environment. Deleting only the main bdb/ folder will likely not solve your OOM.
References
• administration/Meta_recovery.md
• administration/management/FE_configuration.mddarshit.jain
08/26/2026, 5:57 AMRocky
08/26/2026, 5:57 AMConcGCThreads instead of the ZGC-specific flag, or having a conflict with the default fe.conf settings.
Correct JAVA_OPTS for ZGC in fe.conf
Add (or modify) the following line in your fe/conf/fe.conf. Important: You must remove or comment out any existing -XX:+UseG1GC line.
bash
# Example for a node with 32GB RAM and 8-16 cores
JAVA_OPTS="-Xmx24g -Xms24g -XX:+UseZGC -XX:ZConcGCThreads=4 -XX:+UseNUMA"
Key Parameters Explained:
1. -XX:+UseZGC: Enables the Z Garbage Collector.
2. -XX:ZConcGCThreads=<N>: This is the correct flag for ZGC concurrent threads.
* The "Not Working" Issue: Many users try -XX:ConcGCThreads, but for ZGC, the specific flag is ZConcGCThreads.
* Recommendation: Set this to roughly 25% of your available CPU cores. If set too high, the GC will compete with FE metadata replay/processing; if too low, it won't keep up with the 4.5M journal entry churn.
3. -Xmx and -Xms: For ZGC, it is highly recommended to set the minimum and maximum heap sizes to the same value to prevent the JVM from stalling while resizing the heap.
4. -XX:+UseNUMA: ZGC is NUMA-aware. Enabling this significantly improves performance on multi-socket servers.
Why thread changes might still "fail":
* Duplicate JAVA_OPTS: Check if your fe.conf has multiple JAVA_OPTS lines. The last one usually wins, or they are concatenated depending on the version of start_fe.sh.
* StarRocks Overrides: Open bin/start_fe.sh and check if there are hardcoded defaults like -XX:+UseG1GC. If your fe.conf doesn't override them correctly, the FE might fail to start due to "conflicting collector" errors.
* JDK Version: Ensure java -version returns JDK 17+. ZGC in JDK 8/11 is experimental and uses different flags.
Verifying the Change
After restarting the FE, check the fe.gc.log (or fe.out). You should see a line confirming the collector:
Using The Z Garbage Collector
If you see an error like Conflicting collector combinations in option list, it means an old -XX:+UseG1GC or -XX:+UseParallelGC flag is still hiding in your configuration.
References
• administration/management/FE_configuration.md
• faq/operation_maintenance_faq.md
• deployment/environment_configurations.md
References
• administration/management/FE_configuration.md
• deployment/environment_configurations.md
• administration/management/compaction.md
• knowledge/admin_and_operation/shared_data_compaction.md
• administration/management/logs.md
• administration/management/BE_configuration.md
• sql-reference/sql-functions/JAVA_UDF.mddarshit.jain
08/26/2026, 6:52 AMimage.5369484) for a cluster with 38 tablets, 10 tables. The global_state image is 11.7 MB. That's 140× larger for the same cluster.
There's also an image.ckpt of 95 MB dated Aug 15 21:00 — 18h after the last complete image — presumably a failed checkpoint remnant.
What would make a StarManager image 1.65 GB on a 38-tablet cluster? Orphaned shards from failed StarMgrMetaSyncer.cleanOneGroup() (we see GRPC:DEADLINE_EXCEEDED on shard group deletion)? Is there a way to prune orphaned shard metadata?
This affects our recovery choice — even after discarding the journal, we'd still be loading a 1.65 GB image, so we need to know whether that alone is sustainable.Rocky
08/26/2026, 6:53 AMimage.5369484 file.
* Memory Pressure: When the FE restarts, it tries to deserialize this 1.65 GB file into Java objects. In-memory, a 1.65 GB serialized file can easily expand to 10–20 GB of Heap due to object overhead, which explains your 15 GB OOM.
Sustainability & Recovery
Loading a 1.65 GB StarManager image for 38 valid tablets is not sustainable. The FE will likely remain unstable, OOM-ing during every checkpoint or whenever the StarMgrMetaSyncer thread wakes up to scan the metadata.
1. Can you prune them?
The StarMgrMetaSyncer is designed to find these orphans by comparing the FE's Tablet Inverted Index with StarManager's Shard list.
* The Problem: Because the bloat is so massive, the syncer is hitting GRPC:DEADLINE_EXCEEDED. It is trying to list 4.5 million shards over an internal RPC call that times out before it can finish the "diff."
* Config to try: You can try increasing the timeout and the sync interval to give it room to work (add to fe.conf):
properties
# Give the syncer more time to process the massive orphan list
starmgr_grpc_timeout_seconds = 300
# Slow down the sync frequency so it doesn't thrash
star_mgr_meta_sync_interval_sec = 1200
2. The "Nuclear" Recovery (Recommended for your scale)
Since you only have 10 tables and 38 tablets, the most reliable way to fix this is to bypass the broken StarManager state entirely:
1. Script your DDL: Use SHOW CREATE TABLE for your 10 tables (if the FE stays up long enough) or pull them from your CI/CD.
2. Wipe Metadata:
* Stop all FEs.
* Delete the entire meta/ directory (this wipes GlobalState AND StarOS/StarManager).
3. Clean Object Storage: Manually delete the data in your S3/Object storage bucket to ensure no "shadow" data files remain.
4. Restart & Re-init: Start the FE as a fresh node and re-run your 10 DDLs.
Why this is better: Trying to "heal" a StarManager that is 140x bloated will take days of background "vacuuming" and likely several more OOM crashes. At your scale (10 tables), a fresh start takes 10 minutes and guarantees a clean, 11 MB metadata state.
How to inspect StarManager (Optional)
If you can get the FE to stay alive for a few minutes with a massive heap (e.g., -Xmx32g), you can verify the orphan count:
* SHOW PROC '/starmgr/shards'; (Warning: This will likely hang or OOM if there are 4M+ entries).
* SHOW PROC '/starmgr/shard_groups';Rocky
08/26/2026, 6:53 AMdarshit.jain
08/26/2026, 6:53 AMRocky
08/26/2026, 6:54 AMSHOW CREATE TABLE <table_name> for each table.
* Note down your Storage Volume configuration (SHOW STORAGE VOLUMES and DESC STORAGE VOLUME <name>). You will need the S3 credentials and endpoint again.
2. Shutdown the Cluster
Stop all StarRocks processes to ensure no files are locked.
* FE: bash fe/bin/stop_fe.sh
* CN: bash cn/bin/stop_cn.sh
3. Clear Local Metadata
You must delete the metadata on all FE and CN nodes.
* On every FE node:
bash
rm -rf /path/to/fe/meta/*
(This deletes both the GlobalState BDB logs and the StarOS/StarManager image/journals.)
* On every CN node:
bash
rm -rf /path/to/cn/storage/*
(This clears the local data cache and any temporary metadata the CNs held.)
4. Clear Remote Object Storage (S3/MinIO)
StarRocks metadata "points" to data in your S3 bucket. If you wipe the metadata but leave the data in S3, those files become "unmanaged garbage."
* Go to your S3 bucket/prefix (the one used in your STORAGE VOLUME location).
* Delete the contents under that prefix.
_ _Warning:* Do not delete the bucket itself if other applications use it, just the sub-folders created by StarRocks.
5. Start a Fresh Leader FE
Pick one FE to be your new Leader.
1. Start it normally: bash fe/bin/start_fe.sh --daemon.
2. Connect via MySQL client: mysql -h <fe_ip> -P 9030 -u root.
3. Check the state: SHOW PROC '/starmgr/shards'; should now be empty (or return very quickly).
6. Reconfigure Cluster Infrastructure
Since the metadata was wiped, the FE "forgot" about the CNs and the Storage Volume.
1. Add Compute Nodes (CNs):
sql
ALTER SYSTEM ADD COMPUTE NODE "host:port";
2. Recreate Storage Volume:
Use the DDL you saved in Step 1.
sql
CREATE STORAGE VOLUME my_s3_vol
TYPE = S3
LOCATIONS = ("<s3://bucket/path/>")
PROPERTIES (...);
SET my_s3_vol AS DEFAULT STORAGE VOLUME;
7. Recreate Tables and Load Data
1. Run your CREATE DATABASE and CREATE TABLE statements.
2. Your metadata (image) should now be back to a healthy size (~10–15 MB).
3. Reload your data.
Why this is the "Safe" Path
Trying to manually prune 4.5 million shards using StarMgrMetaSyncer is a "death by a thousand cuts" for the FE's CPU and memory. By wiping the meta/ directory, you are forcing StarManager to start with a clean slate. Because your data scale is small (10 tables), the time it takes to reload is significantly less than the time it would take to debug the metadata OOM.
One Final Tip: Once you recreate the cluster, monitor the FE logs for failed to create tablet or 403 errors. If those reappear, your ingestion script is likely hitting a resource limit or a permission issue that caused the original "orphan storm."
References
• knowledge/admin_and_operation/shared_data_garbage_cleanup.md
• faq/shared_data_faq.md
• deployment/shared_data/s3.mddarshit.jain
08/26/2026, 7:10 AM@Rocky After disabling, all 403s are gone (zero in 12h).builtin_storage_volumenow fails cleanly withTableKeeperbut still retries every 30s — how do we pointStorage volume builtin_storage_volume is disabledat_statistics_, which is alreadydp_gcs_prd?IsDefault: true
On the 1.65 GB star_os image for 38 tablets: we seefailing ~1,555 times/12h andStarletAgent.heartbeat()returningStarMgrMetaSyncer.cleanOneGroup()on shard-group deletion. Could persistently failed shard cleanup explain orphaned shard metadata accumulating to that size? Is there a way to audit or prune orphaned shards?GRPC:DEADLINE_EXCEEDED
Also:is set, yetcheckpoint_only_on_leader = truestill targets fe-2 (a crash-looping follower). Expected?CheckpointController.pushImage()
Rocky
08/26/2026, 7:10 AM_statistics_ to dp_gcs_prd
In shared-data mode, the _statistics_ database and its tables inherit the Default Storage Volume only at the time of their creation. Setting dp_gcs_prd as the default after the cluster was initialized does not retroactively move existing internal tables.
Since builtin_storage_volume is disabled, the TableKeeper (responsible for maintaining these system tables) is stuck. To fix this:
1. Drop the existing statistics database:
sql
DROP DATABASE _statistics_ FORCE;
2. Let the system recreate it: The FE Leader will automatically detect the missing database and recreate it. Because dp_gcs_prd is now your default volume, the new tables will be created on GCS.
3. Verify: Run SHOW CREATE TABLE _statistics_.column_statistics; to confirm the storage_volume property is now dp_gcs_prd.
2. The 1.65 GB star_os Image & Orphaned Shards
Your theory is correct: the persistent failure of shard cleanup is exactly why the metadata has bloated to 1.65 GB for only 38 valid tablets.
* The Logjam: StarMgrMetaSyncer.cleanOneGroup() is responsible for identifying shards that exist in StarOS but not in the FE's Tablet Inverted Index.
* The Deadline: With 4.5 million orphaned shards, the list generated by the syncer is likely exceeding the gRPC message size limit or the starmgr_grpc_timeout_seconds. Because it returns DEADLINE_EXCEEDED, the cleanup transaction never commits, and the 1.65 GB of "trash" metadata remains in every new image checkpoint.
* Audit/Prune: There is no SQL-level "prune" command for StarOS. The system is designed to self-heal via the syncer, but the sheer scale of your "orphan storm" has broken the healer.
Recommendation:
To force the cleanup, you may need to temporarily increase the gRPC timeout in fe.conf to allow the syncer to finish one massive cycle:
properties
starmgr_grpc_timeout_seconds = 300
However, if the image is already 1.65 GB and causing 15 GB heap usage, the FE may OOM before the syncer can finish. The "wipe and recreate" method mentioned previously is the only guaranteed way to purge this metadata volume.
3. pushImage() targeting a crashing Follower
This is Expected Behavior.
* checkpoint_only_on_leader = true: This flag ensures that the heavy work of replaying journals and writing the new image.xxxx file happens only on the Leader.
* Propagation: Once the Leader creates the image, it is required to push it to all Followers (fe-2, etc.) so they can stay in sync and be ready for failover.
* The Logs: Even if fe-2 is in a crash loop, the Leader's CheckpointController will continuously try to fulfill its duty of synchronizing the metadata state to the rest of the cluster. It doesn't know fe-2 is "permanently" broken; it just sees a failed network/RPC attempt.
Summary of Recovery Status
* Recovery sustainable?: No. A 1.65 GB StarOS image for 38 tablets is a "zombie" state. Even if you get it to start, the metadata overhead will cause constant GC pressure and likely future OOMs during checkpoints.
* Action: If you cannot get the Syncer to finish a cleanup cycle with increased timeouts, proceed with the Wipe and Recreate of the meta/ directory to reset the StarOS state to its healthy <10MB size.
References
• knowledge/admin_and_operation/shared_data_compaction.mddarshit.jain
08/26/2026, 7:11 AMRocky
08/26/2026, 7:11 AM_statistics_ database is a standard recovery procedure for the scenario you described (moving internal metadata off a disabled storage volume). While it is safe, there are three specific "issues" or side effects to be aware of:
1. Temporary Query Performance Degradation
When you drop the statistics database, the Cost-Based Optimizer (CBO) loses all metadata about your data distribution (row counts, Min/Max values, Null counts, and NDV).
* Consequence: For a short window after the drop, complex queries (especially those with many joins) may have suboptimal execution plans. The CBO might pick an inefficient join order because it essentially thinks your tables are empty or of unknown size.
* Mitigation: Once the tables are recreated, StarRocks will automatically start background "Analyze" tasks to refill the statistics. You can also manually trigger ANALYZE TABLE <your_table_name>; for your most critical tables to restore their stats immediately.
2. Automatic Recreation is Reactive
The FE Leader will recreate the _statistics_ database and its internal tables (like column_statistics, histogram_statistics) automatically.
* The Volume Fix: Because you set dp_gcs_prd as the default storage volume before the recreation, the new tables will correctly point to your GCS bucket. This will stop the TableKeeper errors you are seeing.
3. "Force" is Recommended
When dropping system databases to fix storage volume issues, use the FORCE keyword:
sql
DROP DATABASE _statistics_ FORCE;
This ensures that the metadata is immediately purged and not held in the FE Recycle Bin, allowing the recreation process to start from a truly clean state on the new volume.
Summary of what happens:
1. Drop: You run DROP DATABASE _statistics_ FORCE;.
2. Recreate: The FE Leader detects the missing system database and recreates it using the current Default Storage Volume (dp_gcs_prd).
3. Refill: Background threads scan your tables to rebuild the stats.
4. Health: The TableKeeper failures and 403 errors related to the builtin_storage_volume will disappear.
Conclusion: It will not cause functional "issues" (your data remains intact), only a temporary period where the optimizer is "blind." Given your current state with the 1.65 GB image and 403 errors, this is a necessary and recommended step.
References
• using_starrocks/Cost_based_optimizer.md
• sql-reference/sql-statements/cbo_stats/DROP_STATS.md
• sql-reference/sql-statements/cbo_stats/DROP_ANALYZE.md
• faq/shared_data_faq.md
• deployment/shared_data/feature-support-shared-data.md
• data_source/catalog/unified_catalog.md
• administration/Meta_recovery.md
• sql-reference/sql-statements/cbo_stats/CREATE_ANALYZE.md
• quick_start/shared-data.md
References
• using_starrocks/Cost_based_optimizer.mddarshit.jain
08/26/2026, 7:15 AMRocky
08/26/2026, 7:16 AMbuiltin_storage_volume was returning 403 errors, Step 2 failed. However, the system (specifically the TableKeeper for _statistics_ or an automated ingestion script) likely kept retrying every few seconds.
* The Leak: Every failed attempt successfully completed "Step 1" (creating shards in StarOS) but failed before "Step 3" could link them to a real table.
* The Result: 4.5 million shards were registered in the StarOS metadata that do not belong to any valid tablet in the StarRocks Catalog.
2. The "Syncer Logjam" (The Bloat)
StarRocks has a background thread called StarMgrMetaSyncer designed to clean up these orphans. It compares the StarOS shard list against the FE's TabletInvertedIndex.
* The Deadline Exceeded: When the orphan count reached a critical mass (millions), the list became so large that the syncer's gRPC calls began exceeding the default starmgr_grpc_timeout_seconds (5–10s).
* The Failure: Because the cleanup task timed out, it never "committed" the deletions. The 4.5 million shards remained in the metadata, and the syncer just kept retrying the same failing, over-sized task.
3. Image & Heap Explosion
In StarRocks, the StarOS metadata is serialized directly into the FE image file and loaded into the JVM Heap at startup.
* File Size: 4.5 million shard entries (containing IDs, replica locations, and status) naturally consume ~1.5–2 GB of disk space when serialized.
* RAM Usage: When the FE tries to deserialize this massive list into Java objects, it requires a significant "expansion factor." This is why you see 15 GB of heap usage for a cluster that technically only has 38 "active" tablets.
Why _statistics_ was the primary culprit
System tables like _statistics_ are managed by the TableKeeper. Unlike user tables, which might stop if a script fails, the TableKeeper is an internal daemon. If it is pointed at a broken volume (builtin_storage_volume), it will persistently attempt to create its internal tablets or update stats, acting as an "orphan factory" that never stops until the volume is fixed or the database is dropped.
Summary
The 403 errors were the spark, but the lack of a "rollback" for StarOS shard allocation on failed commits is what allowed the metadata to leak. Once the leak exceeded the processing capacity of the StarMgrMetaSyncer, the bloat became permanent and self-sustaining.
This is why "Wiping and Recreating" (clearing the meta/ directory) is necessary: The cleanup mechanism is currently "drowning" in its own backlog and cannot recover without a manual reset of the StarOS state.
References
• faq/shared_data_faq.md
• knowledge/admin_and_operation/shared_data_compaction.mddarshit.jain
08/26/2026, 3:09 PMverifyMembership failure after DROP/ADD FOLLOWER
StarRocks 4.0.11, shared-data, 3 FE on the K8s operator.
Yesterday we ran ALTER SYSTEM DROP FOLLOWER then ALTER SYSTEM ADD FOLLOWER for fe-2. The leader now expects it as Id 4, name suffix _1787665752206. But fe-2's local meta/bdb still carries the old identity, Id 2, suffix _1784220843345, so the handshake is rejected:
ERROR [BDBEnvironment.setupEnvironment():306] failed to setup environment after retried 2 times
com.sleepycat.je.EnvironmentFailureException: (JE 18.3.20) Environment must be closed
Caused by: EnvironmentFailureException: Environment invalid because of previous exception:
starrocks-mas-fe-2..._9010_1784220843345(2):/opt/starrocks/fe/meta/bdb Feeder: starrocks-...
at com.sleepycat.je.rep.stream.ReplicaFeederHandshake.verifyMembership(ReplicaFeederHandshake.java:342)
It loops: this node is DETACHED → current role UNKNOWN → retry → fail, ~52s per cycle, then the pod restarts.
Questions:
1. Is there a way to reconcile fe-2's local BDBJE identity with the new cluster membership without clearing meta/? e.g. re-registering it under its original Id 2, or a config flag to accept the existing identity?
2. If clearing is the only path, is it safe to clear *only*`meta/bdb` and keep meta/image, or must the whole meta/ directory go?
3. Alternatively — can we ALTER SYSTEM DROP FOLLOWER the new Id 4 entry and re-add fe-2 under its original name/suffix so the local BDBJE state matches again?
Context: fe-0 and fe-1 are healthy after increasing FE to 48Gi / -Xmx36g. Live set dropped from ~15 GB to 61 MB with zero allocation stalls, so the memory issue is resolved. fe-2 is the only remaining problem, and we have quorum at 2/3.Rocky
08/26/2026, 3:09 PMfe-2 BDBJE identity crisis, here are the answers to your specific questions:
1. Can we reconcile identity without clearing meta/?
No. BDBJE (Berkeley DB Java Edition) uses the node name (which includes that timestamp suffix) as a unique, immutable identifier within its replication group logs.
* The Conflict: The Leader’s BDB logs now have a record for fe-2 as Id 4 with the new suffix. When fe-2 attempts to join with its local logs identifying as Id 2, the BDB handshake fails the verifyMembership check because it sees a name/ID mismatch for the same endpoint.
* Config Flags: There is no configuration flag to "override" or "alias" these identities. BDBJE is designed to be strictly consistent regarding member identity to prevent split-brain scenarios.
2. Is clearing meta/bdb enough?
No, you should clear the entire meta/ directory.
* Why: StarRocks stores node identity in multiple places. Specifically, meta/image/ROLE contains the node name (including the suffix). If you only clear meta/bdb, the FE will start up, read the old name from the ROLE file, and attempt to register with the Leader using the old suffix, leading to the same handshake failure.
* Safety: In shared-data mode, the "Source of Truth" is the Object Store and the FE Leader. Since your Leader has a healthy 61 MB image, fe-2 will download this image and the necessary BDB edit logs in a matter of seconds.
3. Can we re-add fe-2 under its original suffix?
No. The suffix (e.g., _1787665752206) is a Unix timestamp generated automatically by the FE Leader at the moment the ALTER SYSTEM ADD FOLLOWER command is executed. There is no SQL syntax to manually specify a suffix or force the Leader to reuse an old one.
──────────
Recommended Recovery Path for fe-2
Since you are using the K8s operator and have 2/3 quorum, follow this "Clean Slate" procedure:
1. Drop the Zombie Entry: Ensure the Leader is clean. Run this on the Leader:
sql
-- Drop the entry that fe-2 is currently failing to match
ALTER SYSTEM DROP FOLLOWER "starrocks-mas-fe-2.starrocks-mas-fe-service:9010";
2. Clear Local Metadata: Wipe the metadata on the fe-2 pod.
* If using a PersistentVolume, the easiest way is to delete the PVC for fe-2 and let the operator recreate it.
_ Alternatively, exec into the pod (if it stays up long enough) and run rm -rf /opt/starrocks/fe/meta/_.
3. Re-Add the Follower:
sql
ALTER SYSTEM ADD FOLLOWER "starrocks-mas-fe-2.starrocks-mas-fe-service:9010";
4. Restart with Helper:
The operator should handle the restart. Ensure it starts with the --helper flag pointing to fe-0 or fe-1. If the operator detects an empty meta/ directory, it typically performs this "join" logic automatically.
Note on pushImage()
The fact that fe-2 still receives pushImage() attempts is harmless. The Leader is programmed to persistently attempt to synchronize the image to all known members of the frontends table. Once you DROP the old entry and ADD the new one, the Leader will stop targeting the "ghost" identity and start targeting the new Id 4 (or Id 5, etc.).
Summary: Your metadata is now healthy and small. A full wipe of `fe-2`’s meta/ directory is the fastest and only reliable way to sync it with the new cluster identity.
References
• administration/Meta_recovery.md
• deployment/deploy_manually.md
• sql-reference/sql-statements/cluster-management/nodes_processes/ALTER_SYSTEM.mdRocky
08/26/2026, 3:09 PMdarshit.jain
08/26/2026, 3:34 PMRocky
08/26/2026, 3:35 PMfe.conf or the ADD FOLLOWER command. The "correct" ID is simply whatever the Leader generates at the moment you run the SQL command.
Here is how you ensure the pod uses that "correct" ID instead of its old one:
1. The Leader's Role
When you run ALTER SYSTEM ADD FOLLOWER "starrocks-mas-fe-2...:9010", the Leader creates a new record in its internal frontends table. It takes the FQDN and appends a fresh timestamp (e.g., _1787665752206).
* From the Leader's perspective: This is now the only valid identity for that FQDN.
2. The Pod's Role (The "Memory" Problem)
When the fe-2 pod starts up, it checks its local meta/image/ROLE file.
* If the file exists: The pod says, "I am ..._1784220843345 (Id 2)." It then contacts the Leader. The Leader compares this to its table, sees a mismatch (expecting Id 4), and rejects the handshake.
* If the file DOES NOT exist (Clean Slate): The pod starts in "discovery mode." It contacts the --helper node and says, "I am at this FQDN, but I don't know who I am yet." The Leader looks at its table, finds the entry for that FQDN, and tells the pod: "You are Id 4 with this suffix." The pod then saves this to its local ROLE file and begins downloading the 61 MB metadata image.
3. How to guarantee the "Correct" ID is used
To ensure fe-2 adopts the identity the Leader wants it to have, you must remove its memory of the old identity.
The Step-by-Step "Identity Reset":
1. Drop the ghost identities: On the Leader, run SHOW FRONTENDS. Drop every entry associated with fe-2 (both the old Id 2 and the new Id 4) to ensure the Leader's table is clean.
sql
ALTER SYSTEM DROP FOLLOWER "starrocks-mas-fe-2.starrocks-mas-fe-service:9010";
2. Wipe the Pod's Metadata: Since you are on K8s, the most reliable way is to delete the PVC for `fe-2`:
bash
kubectl delete pvc <pvc-name-for-fe-2> -n <namespace>
This is safe because your metadata is shared-data and your Leader (fe-0/fe-1) is healthy.
3. Register the new identity: Now, run the ADD command on the Leader once:
sql
ALTER SYSTEM ADD FOLLOWER "starrocks-mas-fe-2.starrocks-mas-fe-service:9010";
4. Restart the pod: The StarRocks Operator will see the pod is missing/PVC is gone, recreate it, and start it. Because the /meta directory is now empty, the pod will successfully "handshake" with the Leader, accept whatever ID the Leader provides, and join the cluster within seconds.
Summary
You don't need to force an ID; you just need to clear the pod's local state. As long as meta/ is empty, the pod has no choice but to use the "correct" identity provided by the Leader.
References
• sql-reference/sql-statements/cluster-management/nodes_processes/ALTER_SYSTEM.md
• administration/Meta_recovery.md
• deployment/deploy_manually.md
• administration/management/FE_configuration.mdRocky
08/26/2026, 3:35 PMALTER SYSTEM ADD FOLLOWER "fe-2-fqdn:9010", the Leader does not wait for the pod to check in. It immediately:
* Generates a new unique ID (e.g., 4).
* Generates a new unique Suffix/Timestamp (e.g., _1787665752206).
* Stores this in its internal "Frontend Table" as: Host: fe-2-fqdn -> Name: fe-2-fqdn_9010_1787665752206.
2. The "Who Am I?" Handshake
When the fe-2 pod starts with an empty meta/ directory and the --helper flag:
1. Request: fe-2 contacts the Leader and says: "I am a new node at fe-2-fqdn:9010. What is my identity?"
2. Lookup: The Leader looks at its Frontend Table. It sees that fe-2-fqdn:9010 is pre-registered as Id 4 with suffix _1787665752206.
3. Instruction: The Leader tells `fe-2`: _"You are node fe-2-fqdn_9010_1787665752206. Here is the current image and the BDBJE logs."_
4. Acceptance: Because fe-2 has no local identity (since you wiped meta/), it obediently adopts this name, writes it to its new meta/image/ROLE file, and initializes its BDBJE environment with that suffix.
3. Why the mismatch happened before
The mismatch only occurred because your fe-2 pod already had an identity stored in its Persistent Volume.
* Old state: The pod's local meta/ said: _"I am Id 2, suffix 1784220843345."
* Leader state: The Leader said: _"I expect Id 4, suffix 1787665752206."
* Conflict: When fe-2 tried to join, it presented its old identity to the BDBJE replication group. BDBJE saw that the name fe-2-fqdn_9010 was being claimed by two different suffixes (...3345 vs ...5206) and triggered the verifyMembership failure to prevent data corruption.
Summary
The Leader dictates the identity based on the hostname/IP you provide in the ADD FOLLOWER command. The pod only "registers" itself with a new ID if it finds its local identity is missing.
By wiping meta/, you are effectively telling the pod: "Forget who you were; ask the Leader who you are now." Since the Leader only has one entry for that hostname (Id 4), the pod will adopt Id 4 perfectly.
Next Step Recommendation:
1. Run SHOW PROC '/frontends'; on the Leader.
2. If you see an entry for fe-2 with Alive: false, note the name.
3. Wipe `fe-2`'s /opt/starrocks/fe/meta/*.
4. Restart fe-2. It will automatically become the "Id 4" the Leader is waiting for.
References
• administration/Meta_recovery.md
• deployment/deploy_manually.md
• administration/management/FE_configuration.md
• sql-reference/sql-statements/cluster-management/nodes_processes/ALTER_SYSTEM.mddarshit.jain
08/26/2026, 3:37 PMRocky
08/26/2026, 3:37 PMfe-2 back into the cluster, follow these steps in order. This process assumes you have a healthy Leader (fe-0 or fe-1) and are using the StarRocks Kubernetes Operator.
Step 1: Clean the Leader's Registry
First, remove any existing registration for fe-2 that might be causing a conflict. Run this command on your current Leader FE:
sql
-- Replace the host with your actual FQDN/IP if different
ALTER SYSTEM DROP FOLLOWER "starrocks-mas-fe-2.starrocks-mas-fe-service:9010";
Verify with SHOW PROC '/frontends'; that the entry for fe-2 is gone.
Step 2: Wipe the local metadata on fe-2
Because the identity (suffix and ID) is stored on the Persistent Volume (PV), you must wipe it so the node can "re-introduce" itself.
Option A (Recommended for K8s):
Delete the PersistentVolumeClaim (PVC) for fe-2. The operator will automatically recreate a fresh, empty volume.
bash
# Replace with your actual namespace and PVC name
kubectl delete pvc -n <your-namespace> fe-meta-starrocks-mas-fe-2
Option B (Manual Wipe):
If you cannot delete the PVC, exec into the pod and wipe the directory manually:
bash
kubectl exec -it starrocks-mas-fe-2 -n <your-namespace> -- /bin/bash
# Once inside:
rm -rf /opt/starrocks/fe/meta/*
exit
Step 3: Re-register the Follower on the Leader
Now, tell the Leader to expect a new follower at that address. Run this on the Leader FE:
sql
ALTER SYSTEM ADD FOLLOWER "starrocks-mas-fe-2.starrocks-mas-fe-service:9010";
Step 4: Restart the Pod
If you deleted the PVC (Option A), the pod should already be restarting. If you manually wiped it (Option B), restart the pod to trigger the join process:
bash
kubectl delete pod starrocks-mas-fe-2 -n <your-namespace>
Step 5: Verify the Join
Watch the logs of fe-2 to see it download the 61 MB image from the Leader:
bash
kubectl logs -f starrocks-mas-fe-2 -n <your-namespace>
You should see:
1. transfer image from... (Downloading the 61MB image).
2. replaying edit log... (Syncing BDBJE logs).
3. StarRocksFE start successfully.
Finally, check the status from your MySQL client:
sql
SHOW PROC '/frontends';
fe-2 should now show Alive: true and have a new Name with a fresh timestamp suffix.
Why this works:
By dropping the follower and wiping the metadata, you force a "clean handshake." The Leader generates a fresh ID, and the pod, seeing an empty /meta directory, adopts that ID as its own. Since there are no old BDBJE logs to conflict with, the verifyMembership check passes instantly.
References
• administration/Meta_recovery.mdMoreno Garcia
08/26/2026, 7:04 PMdarshit.jain
08/26/2026, 7:58 PM