elastic/elasticsearch · error · IllegalArgumentException

cannot convert object of type [{}] to bytes

Error message

cannot convert object of type [{}] to bytes

What it means

Thrown by FingerprintProcessor.toBytes when the field value is of a Java type the static toBytes helper does not handle. Supported types: String, byte[], Integer, Long, Float, Double, Boolean, ZonedDateTime, Date, and null (null yields empty bytes). Any other type (e.g. a nested List, Map, ArrayList of mixed objects, BigDecimal, or a custom ingest metadata type) reaches the final throw, naming the runtime class.

Source

Thrown at modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/FingerprintProcessor.java:190

            ByteUtils.writeIntLE(zdt.getMonthValue(), zdtBytes, 4);
            ByteUtils.writeIntLE(zdt.getDayOfMonth(), zdtBytes, 8);
            ByteUtils.writeIntLE(zdt.getHour(), zdtBytes, 12);
            ByteUtils.writeIntLE(zdt.getMinute(), zdtBytes, 16);
            ByteUtils.writeIntLE(zdt.getSecond(), zdtBytes, 20);
            ByteUtils.writeIntLE(zdt.getNano(), zdtBytes, 24);
            ByteUtils.writeIntLE(zdt.getOffset().getTotalSeconds(), zdtBytes, 28);
            System.arraycopy(zoneIdBytes, 0, zdtBytes, 32, zoneIdBytes.length);
            return zdtBytes;
        }
        if (value instanceof Date date) {
            byte[] dateBytes = new byte[8];
            ByteUtils.writeLongLE(date.getTime(), dateBytes, 0);
            return dateBytes;
        }
        if (value == null) {
            return new byte[0];
        }
        throw new IllegalArgumentException("cannot convert object of type [" + value.getClass().getName() + "] to bytes");
    }

    public List<String> getFields() {
        return fields;
    }

    public String getTargetField() {
        return targetField;
    }

    public ThreadLocal<Hasher> getThreadLocalHasher() {
        return threadLocalHasher;
    }

    public byte[] getSalt() {
        return salt;
    }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Select only leaf scalar fields (string, number, boolean, date) in the 'fields' list.
  2. For nested values, use a script processor to extract and flatten them into scalar fields before fingerprinting.
  3. Convert unsupported numerics to string with a preceding convert processor (type 'string').
  4. If a field legitimately contains arrays of scalars, ensure they are flattened first; Maps cannot be hashed by this processor.

Example fix

// before - field "tags" is a Map / object, fingerprint rejects it
{"fingerprint": {"fields": ["id", "tags"]}}
// after - flatten or stringify first
{"convert": {"field": "tags", "type": "string", "ignore_missing": true}},
{"fingerprint": {"fields": ["id", "tags"]}}
Defensive patterns

Strategy: type-guard

Validate before calling

// Convert non-string scalars to string before fingerprint, and avoid pointing at objects:
{"convert": {"field": "amount", "type": "string", "ignore_missing": true}}

Type guard

// painless - verify each selected field is a leaf scalar
boolean isHashable(def v) { return v == null || v instanceof String || v instanceof Number || v instanceof Boolean || v instanceof ZonedDateTime || v instanceof JodaCompatibleZonedDateTime; }

Try / catch

{"on_failure": [{"index": {"index": "ingest-dlq"}}]}

Prevention

When it happens

Trigger: Configuring the fingerprint processor on a field that contains an array/object (List or Map) or an unsupported scalar like BigDecimal. The per-field traversal pushes list elements individually, but a value that is itself a non-supported scalar or a Map hits this branch.

Common situations: Field selection mistakes (pointing at nested objects rather than leaf scalars); JSON arrays of objects; BigDecimal/BigInteger values produced by upstream processors; objects inserted by enrichment processors; selecting a field that holds the entire document.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/0cfa9904399f333c. Report an issue: GitHub.