skip to content

How does kafka-consumer-groups --reset-offsets work, and what are the --to-earliest, --shift-by, and --to-datetime modes plus the dry-run/execute safety model?

level: seniorimportance: must knowfreq 70%

answer

  1. group must be inactive (Empty), else it errors
  2. dry-run by default, --execute to apply
  3. to-earliest / to-latest / shift-by / to-offset / to-datetime / by-duration
  4. shift-by negative = replay, positive = skip
  5. --export / --from-file for review + bulk

basics

~20 s

It rewrites a group's committed offsets so it reprocesses or skips records. Modes include --to-earliest (start of log), --to-latest, --shift-by N (relative), and --to-datetime (offsets at a time). The group must be inactive, and by default it's a dry run unless you add --execute.

solid answer

~50 s

kafka-consumer-groups.sh --reset-offsets changes the committed offsets in __consumer_offsets for a group, controlling where it resumes. You pick a scope (--topic t or --topic t:0,1 or --all-topics) and a mode: --to-earliest (oldest retained offset), --to-latest (skip to end), --shift-by N (relative; negative replays, positive skips), --to-offset N (absolute), --to-datetime 2024-01-01T00:00:00.000 (first offset at/after a timestamp), --by-duration PT1H, or --to-current. Critically, the group must have no active members — otherwise it errors ('Assignments can only be reset if the group is inactive'), because live consumers would fight the reset. The command is a dry run by default and only prints the proposed new offsets; you must pass --execute to apply, or --dry-run explicitly. You can capture/replay plans with --export and --from-file. Use it to replay after a bad deploy, skip a poison batch, or seed a new consumer.

go deeper

for a junior

Know reset-offsets exists and changes where a group resumes; needs --execute.

for a middle

Use the main modes correctly and know the group must be stopped first.

for a senior

Choose the right mode per incident, handle clamping/earliest-not-zero, use export/import for change control.

for a principal

Design replay runbooks accounting for idempotent sinks, timestamp-type pitfalls, and transactional desync.

## Why reset offsets A group resumes from its **committed offset** per partition. Resetting that offset lets you **replay** old records (move backward), **skip** bad records (move forward), or seed a brand-new group at a chosen point — without changing the data, only the bookmark. ## Command shape ``` kafka-consumer-groups.sh --bootstrap-server broker:9092 \ --group payment-processor \ --reset-offsets <MODE> \ <SCOPE> \ [--dry-run | --execute] ``` ### Scope (which partitions) - `--topic orders` — all partitions of a topic. - `--topic orders:0,2` — specific partitions. - `--all-topics` — every topic the group has committed offsets for. ### Modes (where to move to) - `--to-earliest` — the **oldest still-retained** offset (log start offset). Not necessarily 0, because old segments may have been deleted by retention. - `--to-latest` — the high water mark; effectively **skip everything** and only read new records. - `--to-offset N` — an **absolute** offset (clamped to the valid range per partition). - `--shift-by N` — **relative** to the current committed offset. `--shift-by -100` replays the last 100 per partition; `--shift-by 100` skips 100. Clamped to log bounds. - `--to-datetime 2024-06-01T08:00:00.000` — for each partition, the **first offset whose timestamp is >= the given time** (uses the offsetsForTimes lookup on record timestamps). If no record is at/after that time, behavior falls to the partition's end. Timestamp format is ISO-8601, optionally with a zone (e.g. `+00:00`). - `--by-duration PT1H` — like to-datetime but **now minus the ISO-8601 duration** (PT1H = 1 hour ago). - `--to-current` — reset to the current committed offset (a no-op-ish baseline, used with export/import). ## The safety model (very important) 1. **Inactive group required.** All members must have left; otherwise you get *"Assignments can only be reset if the group is inactive, but the current state is Stable."* Stop your consumers first (or the group must be Empty). This prevents a live consumer from committing over your reset. 2. **Dry run by default.** With neither flag (or with `--dry-run`), it only **prints** the proposed `GROUP TOPIC PARTITION NEW-OFFSET` table — nothing is written. 3. **--execute** actually commits the new offsets. 4. **Export/import for review or bulk:** `--dry-run ... --export > plan.csv` captures the plan; `--reset-offsets --from-file plan.csv --execute` applies an edited/approved plan. Great for change control and for resetting many topics consistently. ## Common real uses - **Replay after a bad deploy:** stop the group, `--to-datetime` (just before the bad version shipped) or `--shift-by -N`, `--execute`, restart. - **Skip a poison pill batch:** `--shift-by +K` or `--to-offset` past it. - **Bootstrap a derived store:** new group, `--to-earliest`, rebuild state from the full log. ## Edge cases & gotchas - to-earliest is **not** always 0 — retention/compaction may have trimmed the head. - Offsets are **clamped**: shifting past the start/end lands at the boundary, not an error. - Resetting doesn't delete data and doesn't notify running apps; combine with stopping/redeploying consumers. - For exactly-once / transactional consumers, resetting raw offsets can desync downstream state — prefer application-level replay where the sink is idempotent. - `--to-datetime` relies on **record timestamps**, which may be CreateTime or LogAppendTime depending on the topic's `message.timestamp.type`; mismatched producer clocks can make time-based resets imprecise.

  • Why does the reset fail with 'group is inactive' errors, and how do you fix it?
    Reset requires the group to have no active members so a live consumer doesn't commit over the new offsets. Fix it by stopping all consumer instances (group becomes Empty), running the reset with --execute, then restarting them.
  • Does --to-earliest always reset to offset 0?
    No. It resets to the partition's log start offset (oldest still-retained record). Retention deletion or compaction may have removed early segments, so the earliest offset can be far above 0.
  • How would you safely roll back consumption to 1 hour ago across all partitions?
    Stop the group, run --reset-offsets --by-duration PT1H (or --to-datetime with the timestamp) --all-topics --dry-run to inspect, then re-run with --execute, then restart consumers. by-duration uses record timestamps so verify the topic's timestamp type.

saying these in an interview costs you the question

  • Claiming you can reset offsets while consumers are running.
  • Assuming --to-earliest equals offset 0.
  • Forgetting it's a dry run by default and expecting it to apply without --execute.
  • Saying --shift-by uses absolute offsets (it's relative; --to-offset is absolute).
  • Believing reset deletes or rewrites records (it only moves the committed bookmark).

context