redis/jedis · error · IllegalStateException
HashImport ' ' has been discarded
Error message
HashImport '<name>' has been discarded
What it means
HashImportSupport.checkArgs validates a HashImport (a Redis hash-field import fieldset) before use. It throws IllegalStateException when the fieldset has already been discarded (e.g. after a failed prepare or explicit discard), since using it afterward would send stale or invalid state to the server. The name in the message identifies which fieldset was misused.
Solutions
- Create a new HashImport fieldset instance instead of reusing the discarded one
- Check fieldset.isDiscarded() before each import call and rebuild if true
- Fix the root cause that led to the discard (usually a failed prepare/connection error) before retrying
Example fix
// before
HashImport fieldset = buildFieldset();
try {
jedis.himport(namespace, key, fieldset, values);
} catch (JedisException e) {
jedis.himport(namespace, key, fieldset, values); // IllegalStateException: discarded
}
// after
HashImport fieldset = buildFieldset();
try {
jedis.himport(namespace, key, fieldset, values);
} catch (JedisException e) {
HashImport fresh = buildFieldset();
jedis.himport(namespace, key, fresh, values);
} Defensive patterns
Strategy: validation
Validate before calling
if (fieldset == null || fieldset.isDiscarded()) {
fieldset = rebuildFieldset();
} Type guard
boolean usable(HashImport fs) { return fs != null && !fs.isDiscarded(); } Try / catch
try {
hashImportCall(fieldset, values);
} catch (IllegalStateException e) {
if (e.getMessage().contains("discarded")) {
fieldset = rebuildFieldset();
hashImportCall(fieldset, values);
} else throw e;
} Prevention
- Rebuild the fieldset for every import attempt instead of reusing instances
- Check isDiscarded() before each use when fieldsets are long-lived
- Wrap import retries in logic that constructs fresh fieldsets
When it happens
Trigger: Calling a hash-import command method with a HashImport fieldset after discard() was called on it, or after a failed prepare(Connection) left it discarded. checkArgs is invoked as the first step of every fieldset-consuming API call.
Common situations: Reusing a fieldset across two import calls where the first failed mid-way; catching an exception from a previous import and retrying with the same, now-discarded, HashImport object; long-lived fieldset objects held in application state that were discarded during a connection reset.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- HashImport ' ' expects values but got
- Cannot use Jedis when in Multi. Please use Transaction or…
- Cannot use Jedis when in Pipeline. Please use Pipeline or…
- setHostAndPort method has limited capability.
- WATCH inside MULTI is not allowed
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/5e9ec263d24ca871.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/HashImportSupport.java:19
package redis.clients.jedis;
/**
* {@code HIMPORT SET} helpers: client-side argument validation, and the per-connection
* prepare-before-use that a {@code himportSet} {@link CommandObject}'s
* {@linkplain CommandObject#getPreProcessHooks() pre-process hook} runs. The hook is invoked by
* {@link Connection#executeCommand(CommandObject)} once the {@code CommandExecutor} has picked a
* connection — so retry / cluster redirection / failover stay in force — injecting a
* {@code PREPARE} on that connection just before the {@code SET} when the fieldset is not yet
* prepared there.
*/
final class HashImportSupport {
private HashImportSupport() {
}
static void checkArgs(HashImport fieldset, int valueCount) {
if (fieldset.isDiscarded()) {
throw new IllegalStateException("HashImport '" + fieldset.name() + "' has been discarded");
}
if (valueCount != fieldset.size()) {
throw new IllegalArgumentException("HashImport '" + fieldset.name() + "' expects "
+ fieldset.size() + " values but got " + valueCount);
}
}
/**
* Prepare-before-use: if {@code fieldset} is not yet prepared on {@code connection}, send
* {@code HIMPORT PREPARE} and record it in the connection's note. The PREPARE is built here, only
* when actually needed — the common already-prepared case allocates nothing. The caller
* must own the connection.
*/
static void prepareBeforeUse(Connection connection, HashImport fieldset) {
if (!connection.himportState().isPrepared(fieldset.name())) {
connection.executeCommand(new CommandArguments(Protocol.Command.HIMPORT)
.add(Protocol.Keyword.PREPARE).add(fieldset.name()).addObjects(fieldset.fields()));
markPrepared(connection, fieldset);View on GitHub (pinned to 6dac31d4c2)