flyteorg / flyteorg/flyte

[BUG] flytekit: _dnsify can return node IDs over 63 characters or ending in '-', violating the DNS_LABEL contract

Open
#7,994 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
7.5k
Forks
886
Avg merge
1d 14h
Merged PRs (30d)
120

Description

### Flyte & Flytekit version

flytekit: master @ `d69b3fb` (also present in 1.16.x)
Python: 3.12

### Describe the bug

`flytekit.core.utils._dnsify` is the only place flytekit enforces the Kubernetes DNS_LABEL contract. Its own docstring states the result:

> must only consist of alphanumeric (lower-case a-z, and 0-9) and not exceed 63 characters. It's permitted to have '-' character as long as it's not in the first or last positions.

It violates both halves of that contract.

**1. The 63-character cap is applied to the input, not the output.**

The hash-and-truncate step runs *before* the character conversion:

```python
if len(value) >= MAX: # MAX = 63
h = _sha224(value.encode("utf-8")).hexdigest()[:HASH_LEN]
value = "{}-{}".format(h, value[-(MAX - HASH_LEN - 1):])
for ch in value:
...
```

But the conversion *grows* the string: every upper-case character gets a `-` inserted before it. A 62-character camelCase name passes the input check and comes out at 70 characters.

There is a `len(res) < 62` guard on the two places a `-` is appended, but it only suppresses the *separator* — the character itself is still appended unconditionally, so `res` keeps growing well past 63. The guard also silently corrupts the tail of the name: `...SweepStage` becomes `...sweepstage`, with the separator dropped.

**2. Consecutive separators can leave a trailing `-`.**

Each of `_`, `-`, `.` appends a `-` without checking whether the previous character is already a `-`, and only a *single* trailing `-` is stripped at the end. Two adjacent separators at the end of a name therefore produce a label ending in `-`, which is not a valid DNS_LABEL.

**Why it matters:** `_dnsify` is applied to every node ID in `flytekit/tools/translator.py`, to `node_name` overrides in `flytekit/core/node.py`, and to eager execution names in `flytekit/core/worker_queue.py`. Nothing downstream re-validates length or shape, so an over-long or trailing-`-` identifier is serialized into the workflow spec and registered as-is. This is the same class of problem as #7607.

### Expected behavior

`_dnsify` returns a valid DNS_LABEL — at most 63 characters, lower-case alphanumerics and `-`, never leading or trailing with `-` — for every input.

### Additional context to reproduce

```python
from flytekit import task, workflow
from flytekit.core.utils import _dnsify

@task
def t(x: int) -> int:
return x

NAME = "TrainImageClassifierOnLargeDatasetWithHyperparameterSweepStage" # 62 chars

@workflow
def wf(x: int) -> int:
return t(x=x).with_overrides(node_name=NAME)

node_id = wf.nodes[0].id
print(len(node_id), node_id)
# 70 train-image-classifier-on-large-dataset-with-hyperparameter-sweepstage
# ^^^^^^^^^^^ separator dropped

# Length, directly:
print(len(_dnsify("A" * 70))) # 88
print(len(_dnsify("aB" * 40))) # 80
print(len(_dnsify("MyTaskName" * 10))) # 75

# Trailing '-':
print(repr(_dnsify("test.."))) # 'test-' <- invalid DNS_LABEL
print(repr(_dnsify("a.."))) # 'a-' <- invalid DNS_LABEL
```

A fuzz sweep over 300k random inputs drawn from `[A-Za-z0-9_-.$ ]` produces 431 outputs that are not valid DNS_LABELs (over-length or trailing `-`) on current master, and 0 after the fix.

### Screenshots

_No response_

### Are you sure this issue hasn't been raised already?

- [x] Yes

### Have you read the Code of Conduct?

- [x] Yes

Contributor guide

Open the contributing guide

Research direction

Start in flytekit/core/utils.py at _dnsify and reproduce the documented long camelCase and trailing-separator examples. Check its callers in flytekit/tools/translator.py, flytekit/core/node.py, and flytekit/core/worker_queue.py; done means every output is a lowercase Kubernetes DNS_LABEL of at most 63 characters with no leading or trailing hyphen.

Written by the indexing model from the issue text.

Assessment

Tech stack
kubernetes, python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.