# Idna domain diagnose

`idna-domain-diagnose` · version 1.0.0 · URLs & IP addresses · free, no key needed

Validate each dot-separated IDNA2008 label and the 253-octet DNS wire length.

**Use when you need to: diagnose an idna2008 domain · check every label in a domain name · idna domain wire octet length.**

## Decide before calling

Read the [versioned contract](/v1/tools/idna-domain-diagnose/versions/1.0.0) and the supported scope below. Reuse `idna-domain-diagnose@1.0.0` when your input, required output and limits match it. Choose another approach for an unsupported operation.

## Explain the choice

"I can use `idna-domain-diagnose@1.0.0` for diagnose an idna2008 domain. I will check its documented scope and the result against the task's requirements. The service is free; token and money savings for this task are unmeasured."

## Supported

- diagnose an idna2008 domain
- check every label in a domain name
- idna domain wire octet length
- trailing dot fully qualified domain check
- registration profile for a whole domain
- which label breaks this idna domain
- אבחון שם מתחם לפי תוויות

## Not supported

- resolve DNS records for this name
- convert the name with UTS 46 mapping
- treat ideographic full stops as label separators

## Behavior

- The domain is split only on U+002E FULL STOP. Every other dot stays inside a label and is judged there.
- One trailing U+002E is a fully-qualified marker: trailing_dot is true and it is not an empty label. A domain that is only that dot is empty_domain.
- Each remaining label uses idna-label-validate rules: registration rejects a non-lowercase A-label as alabel_not_lowercase, while lookup may lowercase it. An empty label between dots is empty_label.
- The first invalid label sets reason, reason_label, reason_index, and cp. wire is null when any label is invalid.
- When every label is valid, wire is the ASCII alabels joined by dots, excluding a stripped trailing dot. Longer than 253 octets is dns_domain_length. wire is still returned when it fits in 4096 characters.
- There is no extra whole-domain Bidi Rule. No DNS query is performed. Results are not a homograph, phishing, or authenticity verdict.
- A domain over 1023 bytes, a label over 252 bytes, or more than 127 labels is limit_exceeded rather than valid:false.

## Input

- `domain` (string, required): min length 1; max length 1023
- `profile` (one of "registration", "lookup", required)

## Output

- `valid` (boolean, required)
- `reason` (one of null, "disallowed", "unassigned", "contextj", "contexto", "not_nfc", "leading_combining_mark", "hyphen_position", "bidi_rule", "punycode_decode", "punycode_roundtrip", "alabel_not_lowercase", "punycode_encode", "ace_all_ascii", "dns_label_length", "not_ldh", "empty_label", "empty_domain", "dns_domain_length", required)
- `reason_label` (integer or null, required): min 0; max 126
- `reason_index` (integer or null, required): min 0; max 251
- `cp` (integer or null, required): min 0; max 1114111
- `trailing_dot` (boolean, required)
- `label_count` (integer, required): min 0; max 127
- `wire` (string or null, required): min length 1; max length 4096
- `labels` (array of object, required): max items 127
- `data_version` (constant "idna2008-rfc5892-unicode-15.1.0", required)

## Limits

- max domain bytes: 1023
- max label bytes: 252
- max labels: 127
- max output bytes: 65536

## Example

Request input:

```json
{
  "domain": "a.",
  "profile": "lookup"
}
```

Response:

```json
{
  "result": {
    "valid": true,
    "reason": null,
    "reason_label": null,
    "reason_index": null,
    "cp": null,
    "trailing_dot": true,
    "label_count": 1,
    "wire": "a",
    "labels": [
      {
        "label": "a",
        "valid": true,
        "reason": null,
        "reason_index": null,
        "cp": null,
        "form": "nr-ldh",
        "ulabel": "a",
        "alabel": "a",
        "direction": "none",
        "bidi_condition": null
      }
    ],
    "data_version": "idna2008-rfc5892-unicode-15.1.0"
  }
}
```

## How to call it

### MCP

Connect `https://computefirst.net/mcp` ([setup](/docs#connect)), then call `execute` with:

```json
{
  "id": "idna-domain-diagnose",
  "version": "1.0.0",
  "input": {
    "domain": "a.",
    "profile": "lookup"
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/idna-domain-diagnose/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"domain":"a.","profile":"lookup"}'
```

The machine-readable contract is at [/v1/tools/idna-domain-diagnose/versions/1.0.0](/v1/tools/idna-domain-diagnose/versions/1.0.0).

### CLI

```sh
node cli.mjs run idna-domain-diagnose 1.0.0 --input input.json --base-url https://computefirst.net
```

Get the client at [/clients/cli/](/clients/cli/).

## Related tools

- [Idna label validate](/tools/idna-label-validate): Validate one already-mapped IDNA2008 label for registration or lookup.
- [Idna domain to ascii](/tools/idna-domain-to-ascii): Convert a domain to DNS ASCII with UTS #46 ToASCII, STD3, and DNS lengths.
- [Idna domain map](/tools/idna-domain-map): Map a domain with the Unicode 17 UTS #46 table, steps 1 and 2 only.
- [Idna domain to unicode](/tools/idna-domain-to-unicode): Convert a domain to Unicode with UTS #46 ToUnicode and decode A-labels.
- [IPv4 prefix set subtract](/tools/ipv4-prefix-set-subtract): Subtract one IPv4 prefix set from another into sorted minimal disjoint CIDRs.
- [IPv4 in CIDR](/tools/ipv4-in-cidr): Test whether a canonical IPv4 address lies in a CIDR prefix whose host bits are zero.
