# ES|QL query to match a CIDR in a lookup index

**URL:** https://discuss.elastic.co/t/es-ql-query-to-match-a-cidr-in-a-lookup-index/380849
**Category:** Elastic Search
**Tags:** esql
**Created:** [August 7, 2025, 12:48am UTC](https://discuss.elastic.co/t/es-ql-query-to-match-a-cidr-in-a-lookup-index/380849 "2025-08-07T00:48:37Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![rossw](https://avatars.discourse-cdn.com/v4/letter/r/ecb155/32.png) [@rossw](https://discuss.elastic.co/u/rossw)
#### Post date: [August 7, 2025, 12:48am UTC](https://discuss.elastic.co/t/es-ql-query-to-match-a-cidr-in-a-lookup-index/380849/1 "2025-08-07T00:48:37Z")

</div>

Hi there.

I am trying to create an ES|QL query that will match firewall records with a source.ip field against subnets listed as CIDR in a lookup table. Basically I’m trying to find events that originate from certain CIDR blocks.

This is as close as I got:

```sql
from "logs-panw*" | where rule.name == "BLOCKED MFN OUTBOUND" 

|lookup JOIN "air-byod-network" on source.ip 

```

where both the logs-panw\* and the air-byod-network indices contain a field named source.ip.

In the panw index it is an ip field, and in the air index it is an ip\_range field. But this gave me an error message:

> [esql] \> Unexpected error from Elasticsearch: verification\_exception - Found 1 problem line 2:36: Cannot use field [source.ip] with unsupported type [ip\_range]

Is this because the two fields in the join have to be the same type?

Any ideas on how to perform this sort of join/lookup between an Ip address and a CIDR block?

Thanks, Ross

---

<div class="post-metadata">

### Author: ![leandrojmp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/leandrojmp/32/107231_2.png) [@leandrojmp](https://discuss.elastic.co/u/leandrojmp)
#### Post date: [August 7, 2025, 12:58am UTC](https://discuss.elastic.co/t/es-ql-query-to-match-a-cidr-in-a-lookup-index/380849/2 "2025-08-07T00:58:28Z")

</div>

The data type of both fields needs to match, you need the data type in your lookup index to be an `ip` data type, not an `ip_range`.

You will need to expand the CIDR and have one ip address per document, I have a similar lookup index working in this way.

---

<div class="post-metadata">

### Author: ![rossw](https://avatars.discourse-cdn.com/v4/letter/r/ecb155/32.png) [@rossw](https://discuss.elastic.co/u/rossw)
#### Post date: [August 7, 2025, 1:25am UTC](https://discuss.elastic.co/t/es-ql-query-to-match-a-cidr-in-a-lookup-index/380849/3 "2025-08-07T01:25:36Z")

</div>

Yeah, that’s not going to work for us. We have about a hundred subnets we need to match against, and the subnets change, so creating and maintaining thousands of individual IP records is not going to happen.

Thanks anyway.

---

<div class="post-metadata">

### Author: ![rossw](https://avatars.discourse-cdn.com/v4/letter/r/ecb155/32.png) [@rossw](https://discuss.elastic.co/u/rossw)
#### Post date: [August 7, 2025, 5:02am UTC](https://discuss.elastic.co/t/es-ql-query-to-match-a-cidr-in-a-lookup-index/380849/4 "2025-08-07T05:02:15Z")

</div>

I know it’s bad karma to respond to your own question, but just in-case anyone else needs to do this…

I recreated my lookup index:

```auto
put air-byod-network
{
    "settings": {
        "index": {
            "mode": "lookup"
        }
    },
  "mappings": {
    "properties":{
      "name": {
        "type": "keyword"
      },
      "source.ip": {
        "type": "ip_range"
      }
    }
  }
}

```

and used a python script to populate it with docs like:

“name”: “net1”,  
”source.ip”: “10.1.2.3/24”

I then created an enrichment policy:

```auto
put /_enrich/policy/byod-networks
{
  "range": {
    "indices": "air-byod-network",
    "match_field": "source.ip",
    "enrich_fields": "name"
  }
}

```

and then ran the policy:

```auto
put /_enrich/policy/byod-networks/_execute

```

(remember to re-execute the policy every time the contents of the lookup index (air-byod-network in my case) changes.

They by using this ES|QL I was able to filter on just the firewall events that did not happen on my byod networks:

> from "logs-panw\*" | where rule.name == "BLOCKED MFN OUTBOUND"  
> | ENRICH byod-networks ON source.ip  
> | WHERE name is null

that is, the field “name” will be null when the source.ip address in the firewall log does not match one of the CIDR ranges in the lookup index field source.ip

Hope this helps someone else.

Ross
