> For the complete documentation index, see [llms.txt](https://docs.dnscontrol.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dnscontrol.org/language-reference/domain-modifiers/ignore_external_dns.md).

# IGNORE\_EXTERNAL\_DNS

`IGNORE_EXTERNAL_DNS` makes DNSControl automatically detect and ignore DNS records managed by Kubernetes external-dns.

### Background

[External-dns](https://github.com/kubernetes-sigs/external-dns) is a popular Kubernetes controller that synchronizes exposed Kubernetes Services and Ingresses with DNS providers. It creates DNS records automatically based on annotations on your Kubernetes resources.

External-dns uses TXT records to track ownership of the DNS records it manages. These TXT records contain metadata in this format:

```
"heritage=external-dns,external-dns/owner=<owner-id>,external-dns/resource=<resource>"
```

When you have both DNSControl and external-dns managing the same DNS zone, conflicts can occur. DNSControl will try to delete records created by external-dns, and external-dns will recreate them, leading to an endless update cycle.

### How it works

When `IGNORE_EXTERNAL_DNS` is enabled, DNSControl will:

1. Scan existing TXT records for the external-dns heritage marker (`heritage=external-dns`)
2. Parse the TXT record name to determine which DNS record it manages
3. Automatically ignore both the TXT ownership record and the corresponding DNS record

External-dns creates TXT records with prefixes based on record type:

* `a-<name>` for A records
* `aaaa-<name>` for AAAA records
* `cname-<name>` for CNAME records
* `ns-<name>` for NS records
* `mx-<name>` for MX records
* `srv-<name>` for SRV records
* `txt-<name>` for TXT records (when external-dns manages TXT records)

For example, if external-dns creates an A record at `myapp.example.com`, it will also create a TXT record at `a-myapp.example.com` containing the heritage information.

### Usage

{% code title="dnsconfig.js" %}

```javascript
// Default: detect standard external-dns prefixes (a-, cname-, etc.)
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
  IGNORE_EXTERNAL_DNS(),
  // Your static DNS records managed by DNSControl
  A("www", "1.2.3.4"),
  A("mail", "1.2.3.5"),
  MX("@", 10, "mail"),
  // Records created by external-dns (from Kubernetes Ingresses/Services)
  // will be automatically detected and ignored
);
```

{% endcode %}

### Custom Prefix Support

If your external-dns is configured with a custom `--txt-prefix` (as documented in the [external-dns TXT registry docs](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/registry/txt.md#prefixes-and-suffixes)), pass that prefix to `IGNORE_EXTERNAL_DNS()`:

{% code title="dnsconfig.js" %}

```javascript
// If external-dns is configured with --txt-prefix="extdns-"
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
  IGNORE_EXTERNAL_DNS("extdns-"),
  A("www", "1.2.3.4"),
);
```

{% endcode %}

This will match TXT records like `extdns-www`, `extdns-api`, etc.

Without a prefix argument, it detects:

* The default `%{record_type}-` format (prefixes like `a-`, `cname-`, etc.)
* Legacy format (TXT record with same name as managed record)

### Example scenario

Suppose you have:

* A Kubernetes cluster running external-dns with `--txt-owner-id=my-cluster`
* An Ingress resource that creates an A record for `myapp.example.com` pointing to `10.0.0.1`

External-dns will create:

1. An A record: `myapp.example.com` → `10.0.0.1`
2. A TXT record: `a-myapp.example.com` → `"heritage=external-dns,external-dns/owner=my-cluster,external-dns/resource=ingress/default/myapp"`

With `IGNORE_EXTERNAL_DNS` enabled, DNSControl will:

* Detect the TXT record at `a-myapp.example.com` as an external-dns ownership record
* Ignore both the TXT record and the A record at `myapp.example.com`
* Only manage the records you explicitly define in your `dnsconfig.js`

### Comparison with other options

| Feature                               | Use case                                                        |
| ------------------------------------- | --------------------------------------------------------------- |
| `IGNORE_EXTERNAL_DNS`                 | Automatically ignore all external-dns managed records           |
| `IGNORE("*.k8s", "A,AAAA,CNAME,TXT")` | Ignore records under a specific subdomain pattern               |
| `NO_PURGE`                            | Don't delete any records (less precise, records may accumulate) |

### Caveats

#### One per domain

Only one `IGNORE_EXTERNAL_DNS()` should be used per domain. If you call it multiple times, the last prefix wins. If you have multiple external-dns instances with different prefixes managing the same zone, use `IGNORE()` patterns for additional prefixes.

#### TXT Registry Format

This feature relies on external-dns's [TXT registry](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/registry/txt.md), which is the default registry type. The TXT record content format is well-documented:

```
"heritage=external-dns,external-dns/owner=<owner-id>,external-dns/resource=<resource>"
```

This feature detects the `heritage=external-dns` marker in TXT records to identify external-dns managed records.

#### Custom Prefix Support

This feature supports custom prefixes configured via external-dns's `--txt-prefix` flag. If you're using a custom prefix, pass it to `IGNORE_EXTERNAL_DNS()`:

```javascript
// If external-dns uses --txt-prefix="extdns-"
IGNORE_EXTERNAL_DNS("extdns-")

// If external-dns uses --txt-prefix="myprefix-%{record_type}-"
IGNORE_EXTERNAL_DNS("myprefix-")  // The record type part is handled automatically

// If external-dns uses --txt-prefix="extdns-%{record_type}." (period format)
// This is recommended for apex domain support per external-dns docs
IGNORE_EXTERNAL_DNS("extdns-")  // Works with both hyphen and period format
```

Without a prefix argument, it detects:

* Default format: `%{record_type}-` prefix (e.g., `a-`, `cname-`)
* Legacy format: Same name as managed record (no prefix)

**Period Format for Apex Domains**

If you need external-dns to manage apex (root) domain records, the external-dns documentation recommends using a prefix with `%{record_type}` followed by a period:

```yaml
# external-dns deployment args
args:
  - --txt-prefix=extdns-%{record_type}.
```

This creates TXT records like `extdns-a.www` for the `www` A record, and `extdns-a` for the apex A record. DNSControl's `IGNORE_EXTERNAL_DNS` supports both formats:

* Hyphen format: `extdns-a-www` (from `--txt-prefix=extdns-` with default `%{record_type}-`)
* Period format: `extdns-a.www` (from `--txt-prefix=extdns-%{record_type}.`)

**Note:** Suffix-based naming (`--txt-suffix`) is not currently supported.

#### Unsupported Registries

External-dns supports multiple registry types. This feature **only** supports:

* ✅ **TXT registry** (default) - Stores metadata in TXT records

The following registries are **not supported**:

* ❌ **DynamoDB registry** - Stores metadata in AWS DynamoDB
* ❌ **AWS-SD registry** - Stores metadata in AWS Service Discovery
* ❌ **noop registry** - No metadata persistence

#### Legacy TXT Format

External-dns versions prior to v0.16 created TXT records without the record type prefix (e.g., `myapp.example.com` instead of `a-myapp.example.com`). This legacy format is supported but may match more records than intended since the record type cannot be determined.

### See also

* [`IGNORE`](/language-reference/domain-modifiers/ignore.md) for manually ignoring specific records with glob patterns
* [`NO_PURGE`](/language-reference/domain-modifiers/no_purge.md) for preventing deletion of all unmanaged records
* [External-dns documentation](https://github.com/kubernetes-sigs/external-dns)
