redis/jedis · error · UnsupportedOperationException

HIMPORT is not supported on

Error message

HIMPORT is not supported on <ClassName>; use a single-connection pipeline or himportSet on the client

What it means

PipeliningBase.himportSet(String, HashImport, String...) throws UnsupportedOperationException because HIMPORT requires a lazily-injected PREPARE command on the same physical connection as the subsequent SET. That guarantee only exists on a single-connection pipeline; on transactions MULTI would desync EXEC, and on cluster pipelines a keyless PREPARE cannot be routed by hash slot. The message names the concrete subclass (e.g. Transaction, ClusterPipeliningBase) so the user knows which pipeline type rejected the call.

Solutions

  1. Use a single-connection Pipeline (obtained from a standalone Jedis/RedisClient connection) instead of a transaction or cluster pipeline when you need pipelined himportSet.
  2. If you are inside a transaction, move the himportSet call outside MULTI/EXEC and issue it directly on the client (client.himportSet(...)).
  3. If you are on a cluster, issue himportSet directly on the RedisClusterClient (which routes the PREPARE+SET pair) rather than through a cluster pipeline.
  4. Replace the HIMPORT usage with regular pipelined hset/hsetex commands if you cannot change pipeline type.

Example fix

// before (transaction — throws)
try (Transaction tx = jedis.multi()) {
  tx.himportSet("user:1", fieldset, "a", "1", "b", "2");
  tx.exec();
}

// after (single-connection pipeline or direct client call)
Response<String> resp;
try (Pipeline p = jedis.pipelined()) {
  resp = p.himportSet("user:1", fieldset, "a", "1", "b", "2");
  p.sync();
}
// or simply: jedis.himportSet("user:1", fieldset, "a", "1", "b", "2");
Defensive patterns

Strategy: try-catch

Validate before calling

// Before pipelining, verify the pipeline type supports HIMPORT
if (!(pipeline instanceof Pipeline) || pipeline instanceof Transaction) {
    throw new IllegalStateException("himportSet requires a single-connection Pipeline; use jedis.pipelined() or call client.himportSet directly");
}

Type guard

boolean supportsHimport(PipeliningBase p) {
    return p.getClass().getSimpleName().equals("Pipeline");
}

Try / catch

try {
    response = pipeline.himportSet(key, fieldset, values);
} catch (UnsupportedOperationException e) {
    // fall back to direct client call
    response = new Response<>(BuilderFactory.STRING);
    client.himportSet(key, fieldset, values);
}

Prevention

When it happens

Trigger: Calling himportSet(String key, HashImport fieldset, String... values) on a PipeliningBase subclass that is not a single-connection Pipeline — e.g. inside a MULTI/EXEC transaction (Transaction) or on a cluster pipeline (ClusterPipeliningBase / cluster client pipelining).

Common situations: Using redis.clients.jedis.Transaction and expecting hash-import pipelining to work like normal pipelined commands; calling himportSet on a RedisClusterClient pipeline where slot-based routing cannot handle the keyless PREPARE; copy-pasting single-connection pipeline code into a transaction or cluster context; upgrading Jedis and discovering HIMPORT is only available on Pipeline and direct client calls.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/f2b600ead1e293ae. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/PipeliningBase.java:935

    return appendCommand(commandObjects.httl(key, fields));
  }

  @Override
  public Response<List<Long>> hpttl(String key, String... fields) {
    return appendCommand(commandObjects.hpttl(key, fields));
  }

  @Override
  public Response<List<Long>> hpersist(String key, String... fields) {
    return appendCommand(commandObjects.hpersist(key, fields));
  }

  // HIMPORT needs a lazily-injected PREPARE on the same physical connection as the SET. That is only
  // well-defined on a single-connection pipeline (see Pipeline#himportSet); a transaction (MULTI
  // would desync EXEC) and a cluster pipeline (keyless PREPARE cannot be routed by slot) reject it.
  @Override
  public Response<String> himportSet(String key, HashImport fieldset, String... values) {
    throw himportUnsupported();
  }

  @Override
  public Response<String> himportSet(byte[] key, HashImport fieldset, byte[]... values) {
    throw himportUnsupported();
  }

  UnsupportedOperationException himportUnsupported() {
    return new UnsupportedOperationException(
        "HIMPORT is not supported on " + getClass().getSimpleName()
            + "; use a single-connection pipeline or himportSet on the client");
  }

  @Override
  public Response<Long> sadd(String key, String... members) {
    return appendCommand(commandObjects.sadd(key, members));
  }

View on GitHub (pinned to 6dac31d4c2)